Skip to content

Commit 0be4976

Browse files
committed
Auto merge of #162032 - sjwang05:more-region-dedup, r=<try>
remove more trivial regions in evaluate_added_goals_and_make_canonical_response
2 parents 5321a4f + bc71d10 commit 0be4976

1 file changed

Lines changed: 57 additions & 3 deletions

File tree

  • compiler/rustc_next_trait_solver/src/solve/eval_ctxt

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::ControlFlow;
33

44
#[cfg(feature = "nightly")]
55
use rustc_macros::StableHash;
6-
use rustc_type_ir::data_structures::HashSet;
6+
use rustc_type_ir::data_structures::{HashMap, HashSet};
77
use rustc_type_ir::inherent::*;
88
use rustc_type_ir::region_constraint::{RegionConstraint, evaluate_solver_constraint};
99
use rustc_type_ir::relate::Relate;
@@ -18,8 +18,8 @@ use rustc_type_ir::solve::{
1818
};
1919
use rustc_type_ir::{
2020
self as ty, CanonicalVarValues, ClauseKind, InferCtxtLike, Interner, MayBeErased,
21-
OpaqueTypeKey, PredicateKind, Region, TypeFoldable, TypeSuperVisitable, TypeVisitable,
22-
TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars,
21+
OpaqueTypeKey, PredicateKind, Region, RegionVid, TypeFoldable, TypeSuperVisitable,
22+
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, eager_resolve_vars,
2323
};
2424
use thin_vec::ThinVec;
2525
use tracing::{Level, debug, instrument, trace, warn};
@@ -1608,6 +1608,60 @@ where
16081608
r.retain(|(outlives, _)| !outlives.is_trivial() && unique.insert(*outlives));
16091609
}
16101610

1611+
#[derive(Default)]
1612+
struct TrivialVars {
1613+
counts: HashMap<RegionVid, usize>,
1614+
}
1615+
impl<I> TypeVisitor<I> for TrivialVars
1616+
where
1617+
I: Interner,
1618+
{
1619+
type Result = ();
1620+
fn visit_ty(&mut self, t: I::Ty) {
1621+
// If a nested type doesn't have any `ReVar`s, then visiting it won't affect
1622+
// our `counts` anyway, so skip visiting it entirely for better perf.
1623+
if !t.has_infer_regions() {
1624+
return;
1625+
}
1626+
t.super_visit_with(self);
1627+
}
1628+
fn visit_const(&mut self, c: I::Const) {
1629+
// The same goes for consts.
1630+
if !c.has_infer_regions() {
1631+
return;
1632+
}
1633+
c.super_visit_with(self);
1634+
}
1635+
fn visit_region(&mut self, r: Region<I>) {
1636+
if let ty::ReVar(vid) = r.kind() {
1637+
*self.counts.entry(vid).or_insert(0) += 1;
1638+
}
1639+
}
1640+
}
1641+
1642+
// If we have a constraint like `'re: '?1`, and `?1` appears nowhere else in the response
1643+
// besides the constraint itself, then this kind of constraint is also trivial, since
1644+
// one can always pick `'?1 := 'empty`, and `'re: 'empty` is always true for any 're.
1645+
if !external_constraints.region_constraints.is_empty() {
1646+
let mut vis = TrivialVars::default();
1647+
var_values.visit_with(&mut vis);
1648+
external_constraints.visit_with(&mut vis);
1649+
1650+
if let ExternalRegionConstraints::Old(r) = &mut external_constraints.region_constraints
1651+
{
1652+
r.retain(|(outlives, _)| {
1653+
if let ty::RegionConstraint::Outlives(ty::OutlivesClause(sup, re)) = *outlives
1654+
&& sup.as_region().is_some()
1655+
&& let ty::RegionKind::ReVar(vid) = re.kind()
1656+
{
1657+
vis.counts.get(&vid).is_some_and(|c| *c > 1)
1658+
} else {
1659+
true
1660+
}
1661+
});
1662+
}
1663+
}
1664+
16111665
let canonical = canonicalize_response(
16121666
self.delegate,
16131667
self.max_input_universe,

0 commit comments

Comments
 (0)