Skip to content

Commit aa1b296

Browse files
Unify normalization of terms in deeply normalize
1 parent 7efd90a commit aa1b296

File tree

4 files changed

+30
-71
lines changed

4 files changed

+30
-71
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,13 @@ impl<'tcx> InferCtxt<'tcx> {
823823
ty::Region::new_var(self.tcx, region_var)
824824
}
825825

826+
pub fn next_term_var_of_kind(&self, term: ty::Term<'tcx>, span: Span) -> ty::Term<'tcx> {
827+
match term.kind() {
828+
ty::TermKind::Ty(_) => self.next_ty_var(span).into(),
829+
ty::TermKind::Const(_) => self.next_const_var(span).into(),
830+
}
831+
}
832+
826833
/// Return the universe that the region `r` was created in. For
827834
/// most regions (e.g., `'static`, named regions from the user,
828835
/// etc) this is the root universe U0. For inference variables or

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
206206
let infcx = self.goal.infcx;
207207
match goal.predicate.kind().no_bound_vars() {
208208
Some(ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })) => {
209-
let unconstrained_term = match term.kind() {
210-
ty::TermKind::Ty(_) => infcx.next_ty_var(span).into(),
211-
ty::TermKind::Const(_) => infcx.next_const_var(span).into(),
212-
};
209+
let unconstrained_term = infcx.next_term_var_of_kind(term, span);
213210
let goal =
214211
goal.with(infcx.tcx, ty::NormalizesTo { alias, term: unconstrained_term });
215212
// We have to use a `probe` here as evaluating a `NormalizesTo` can constrain the

compiler/rustc_trait_selection/src/solve/normalize.rs

Lines changed: 21 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::assert_matches::assert_matches;
21
use std::fmt::Debug;
32

43
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -96,66 +95,18 @@ impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>
9695
where
9796
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
9897
{
99-
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
100-
assert_matches!(alias_ty.kind(), ty::Alias(..));
101-
102-
let infcx = self.at.infcx;
103-
let tcx = infcx.tcx;
104-
let recursion_limit = tcx.recursion_limit();
105-
if !recursion_limit.value_within_limit(self.depth) {
106-
let ty::Alias(_, data) = *alias_ty.kind() else {
107-
unreachable!();
108-
};
109-
110-
self.at.infcx.err_ctxt().report_overflow_error(
111-
OverflowCause::DeeplyNormalize(data.into()),
112-
self.at.cause.span,
113-
true,
114-
|_| {},
115-
);
116-
}
117-
118-
self.depth += 1;
119-
120-
let new_infer_ty = infcx.next_ty_var(self.at.cause.span);
121-
let obligation = Obligation::new(
122-
tcx,
123-
self.at.cause.clone(),
124-
self.at.param_env,
125-
ty::PredicateKind::AliasRelate(
126-
alias_ty.into(),
127-
new_infer_ty.into(),
128-
ty::AliasRelationDirection::Equate,
129-
),
130-
);
131-
132-
self.fulfill_cx.register_predicate_obligation(infcx, obligation);
133-
self.select_all_and_stall_coroutine_predicates()?;
134-
135-
// Alias is guaranteed to be fully structurally resolved,
136-
// so we can super fold here.
137-
let ty = infcx.resolve_vars_if_possible(new_infer_ty);
138-
let result = ty.try_super_fold_with(self)?;
139-
self.depth -= 1;
140-
Ok(result)
141-
}
142-
143-
fn normalize_unevaluated_const(
98+
fn normalize_alias_term(
14499
&mut self,
145-
alias_ct: ty::Const<'tcx>,
146-
) -> Result<ty::Const<'tcx>, Vec<E>> {
147-
assert_matches!(alias_ct.kind(), ty::ConstKind::Unevaluated(..));
148-
100+
alias_term: ty::Term<'tcx>,
101+
) -> Result<ty::Term<'tcx>, Vec<E>> {
149102
let infcx = self.at.infcx;
150103
let tcx = infcx.tcx;
151104
let recursion_limit = tcx.recursion_limit();
152105
if !recursion_limit.value_within_limit(self.depth) {
153-
let ty::ConstKind::Unevaluated(uv) = alias_ct.kind() else {
154-
unreachable!();
155-
};
106+
let term = alias_term.to_alias_term().unwrap();
156107

157108
self.at.infcx.err_ctxt().report_overflow_error(
158-
OverflowCause::DeeplyNormalize(uv.into()),
109+
OverflowCause::DeeplyNormalize(term),
159110
self.at.cause.span,
160111
true,
161112
|_| {},
@@ -164,14 +115,14 @@ where
164115

165116
self.depth += 1;
166117

167-
let new_infer_ct = infcx.next_const_var(self.at.cause.span);
118+
let infer_term = infcx.next_term_var_of_kind(alias_term, self.at.cause.span);
168119
let obligation = Obligation::new(
169120
tcx,
170121
self.at.cause.clone(),
171122
self.at.param_env,
172123
ty::PredicateKind::AliasRelate(
173-
alias_ct.into(),
174-
new_infer_ct.into(),
124+
alias_term.into(),
125+
infer_term.into(),
175126
ty::AliasRelationDirection::Equate,
176127
),
177128
);
@@ -181,8 +132,13 @@ where
181132

182133
// Alias is guaranteed to be fully structurally resolved,
183134
// so we can super fold here.
184-
let ct = infcx.resolve_vars_if_possible(new_infer_ct);
185-
let result = ct.try_super_fold_with(self)?;
135+
let term = infcx.resolve_vars_if_possible(infer_term);
136+
// super-folding the `term` will directly fold the `Ty` or `Const` so
137+
// we have to match on the term and super-fold them manually.
138+
let result = match term.kind() {
139+
ty::TermKind::Ty(ty) => ty.try_super_fold_with(self)?.into(),
140+
ty::TermKind::Const(ct) => ct.try_super_fold_with(self)?.into(),
141+
};
186142
self.depth -= 1;
187143
Ok(result)
188144
}
@@ -242,7 +198,8 @@ where
242198
if ty.has_escaping_bound_vars() {
243199
let (ty, mapped_regions, mapped_types, mapped_consts) =
244200
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ty);
245-
let result = ensure_sufficient_stack(|| self.normalize_alias_ty(ty))?;
201+
let result =
202+
ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type();
246203
Ok(PlaceholderReplacer::replace_placeholders(
247204
infcx,
248205
mapped_regions,
@@ -252,7 +209,7 @@ where
252209
result,
253210
))
254211
} else {
255-
ensure_sufficient_stack(|| self.normalize_alias_ty(ty))
212+
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ty.into()))?.expect_type())
256213
}
257214
}
258215

@@ -269,7 +226,8 @@ where
269226
if ct.has_escaping_bound_vars() {
270227
let (ct, mapped_regions, mapped_types, mapped_consts) =
271228
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, ct);
272-
let result = ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct))?;
229+
let result =
230+
ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const();
273231
Ok(PlaceholderReplacer::replace_placeholders(
274232
infcx,
275233
mapped_regions,
@@ -279,7 +237,7 @@ where
279237
result,
280238
))
281239
} else {
282-
ensure_sufficient_stack(|| self.normalize_unevaluated_const(ct))
240+
Ok(ensure_sufficient_stack(|| self.normalize_alias_term(ct.into()))?.expect_const())
283241
}
284242
}
285243
}

compiler/rustc_trait_selection/src/traits/structural_normalize.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ impl<'tcx> At<'_, 'tcx> {
3939
return Ok(term);
4040
}
4141

42-
let new_infer = match term.kind() {
43-
ty::TermKind::Ty(_) => self.infcx.next_ty_var(self.cause.span).into(),
44-
ty::TermKind::Const(_) => self.infcx.next_const_var(self.cause.span).into(),
45-
};
42+
let new_infer = self.infcx.next_term_var_of_kind(term, self.cause.span);
4643

4744
// We simply emit an `alias-eq` goal here, since that will take care of
4845
// normalizing the LHS of the projection until it is a rigid projection

0 commit comments

Comments
 (0)