Skip to content

Commit d3ce9de

Browse files
Do not canonicalize in new solver if it has nothing to canonicalize
1 parent 84a3255 commit d3ce9de

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

compiler/rustc_next_trait_solver/src/canonicalizer.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
44
use rustc_type_ir::inherent::*;
55
use rustc_type_ir::solve::{Goal, QueryInput};
66
use rustc_type_ir::{
7-
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarKind, InferCtxtLike, Interner,
8-
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
7+
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarKind, Flags, InferCtxtLike, Interner,
8+
TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
99
};
1010

1111
use crate::delegate::SolverDelegate;
@@ -79,7 +79,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
7979
cache: Default::default(),
8080
};
8181

82-
let value = value.fold_with(&mut canonicalizer);
82+
let value = if value.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
83+
value.fold_with(&mut canonicalizer)
84+
} else {
85+
value
86+
};
8387
assert!(!value.has_infer(), "unexpected infer in {value:?}");
8488
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
8589
let (max_universe, variables) = canonicalizer.finalize();
@@ -111,7 +115,14 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
111115

112116
cache: Default::default(),
113117
};
114-
let param_env = input.goal.param_env.fold_with(&mut env_canonicalizer);
118+
119+
let param_env = input.goal.param_env;
120+
let param_env = if param_env.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
121+
param_env.fold_with(&mut env_canonicalizer)
122+
} else {
123+
param_env
124+
};
125+
115126
debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST);
116127
// Then canonicalize the rest of the input without keeping `'static`
117128
// while *mostly* reusing the canonicalizer from above.
@@ -134,10 +145,24 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
134145
cache: Default::default(),
135146
};
136147

137-
let predicate = input.goal.predicate.fold_with(&mut rest_canonicalizer);
148+
let predicate = input.goal.predicate;
149+
let predicate = if predicate.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
150+
predicate.fold_with(&mut rest_canonicalizer)
151+
} else {
152+
predicate
153+
};
138154
let goal = Goal { param_env, predicate };
139-
let predefined_opaques_in_body =
140-
input.predefined_opaques_in_body.fold_with(&mut rest_canonicalizer);
155+
156+
let predefined_opaques_in_body = input.predefined_opaques_in_body;
157+
let predefined_opaques_in_body = if input
158+
.predefined_opaques_in_body
159+
.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER)
160+
{
161+
predefined_opaques_in_body.fold_with(&mut rest_canonicalizer)
162+
} else {
163+
predefined_opaques_in_body
164+
};
165+
141166
let value = QueryInput { goal, predefined_opaques_in_body };
142167

143168
assert!(!value.has_infer(), "unexpected infer in {value:?}");
@@ -387,7 +412,11 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
387412
| ty::Alias(_, _)
388413
| ty::Bound(_, _)
389414
| ty::Error(_) => {
390-
return ensure_sufficient_stack(|| t.super_fold_with(self));
415+
return if t.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
416+
ensure_sufficient_stack(|| t.super_fold_with(self))
417+
} else {
418+
t
419+
};
391420
}
392421
};
393422

@@ -522,11 +551,25 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for Canonicaliz
522551
| ty::ConstKind::Unevaluated(_)
523552
| ty::ConstKind::Value(_)
524553
| ty::ConstKind::Error(_)
525-
| ty::ConstKind::Expr(_) => return c.super_fold_with(self),
554+
| ty::ConstKind::Expr(_) => {
555+
return if c.has_type_flags(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
556+
c.super_fold_with(self)
557+
} else {
558+
c
559+
};
560+
}
526561
};
527562

528563
let var = self.get_or_insert_bound_var(c, kind);
529564

530565
Const::new_anon_bound(self.cx(), self.binder_index, var)
531566
}
567+
568+
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
569+
if p.flags().intersects(TypeFlags::NEEDS_CANONICAL_NEXT_SOLVER) {
570+
p.super_fold_with(self)
571+
} else {
572+
p
573+
}
574+
}
532575
}

compiler/rustc_next_trait_solver/src/resolve.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,8 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> TypeFolder<I> for EagerResolv
8686
}
8787
}
8888
}
89+
90+
fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
91+
if p.has_infer() { p.super_fold_with(self) } else { p }
92+
}
8993
}

compiler/rustc_type_ir/src/flags.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ bitflags::bitflags! {
130130

131131
/// Does this have any binders with bound vars (e.g. that need to be anonymized)?
132132
const HAS_BINDER_VARS = 1 << 23;
133+
134+
// Does this have infer/placeholder/param, free regions or ReErased?
135+
const NEEDS_CANONICAL_NEXT_SOLVER = TypeFlags::HAS_INFER.bits()
136+
| TypeFlags::HAS_PLACEHOLDER.bits()
137+
| TypeFlags::HAS_PARAM.bits()
138+
| TypeFlags::HAS_FREE_REGIONS.bits()
139+
| TypeFlags::HAS_RE_ERASED.bits();
133140
}
134141
}
135142

0 commit comments

Comments
 (0)