Skip to content

Commit a3e96d8

Browse files
committed
Auto merge of #155767 - adwinwhite:eager-norm-outside, r=lcnr
`-Znext-solver` Eager normalization outside of solver This PR adds a normalization routine for the next solver that behaves the same as the normalization in the old solver. The new routine is used to normalize eagerly outside of the next solver. This is [part 2](https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/Eager.20normalization.2C.20ahoy.21/near/582996783) of modifying the next solver to support eager normalization. Those test changes are mostly wording changes, duplicating some errors or reducing some duplicates. But I could have overlooked something. Notably it fixes the first, third and fourth examples in rust-lang/trait-system-refactor-initiative#191, but not the second variant. It's probably easier to review commit by commit. Fixes #151308 Fixes #101557 Fixes #119692 Fixes #136859
2 parents 20de910 + 03cabe7 commit a3e96d8

139 files changed

Lines changed: 1128 additions & 1471 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ use rustc_middle::mir::{Body, ConstraintCategory};
88
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast};
99
use rustc_span::Span;
1010
use rustc_span::def_id::DefId;
11-
use rustc_trait_selection::solve::NoSolution;
1211
use rustc_trait_selection::traits::ObligationCause;
13-
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1412
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
1513
use tracing::{debug, instrument};
1614

@@ -242,71 +240,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
242240
body.source.def_id().expect_local(),
243241
);
244242

245-
if self.infcx.next_trait_solver() {
246-
let param_env = self.infcx.param_env;
247-
// FIXME: Make this into a real type op?
248-
self.fully_perform_op(
249-
location.to_locations(),
250-
ConstraintCategory::Boring,
251-
CustomTypeOp::new(
252-
|ocx| {
253-
let structurally_normalize = |ty| {
254-
ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty))
255-
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
256-
};
257-
258-
let tail = tcx.struct_tail_raw(
259-
ty,
260-
&cause,
261-
structurally_normalize,
262-
|| {},
263-
);
264-
265-
Ok(tail)
266-
},
267-
"normalizing struct tail",
268-
),
269-
)
270-
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
271-
} else {
272-
let mut normalize = |ty| self.normalize(ty, location);
273-
let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {});
274-
normalize(tail)
275-
}
276-
}
277-
278-
#[instrument(skip(self), level = "debug")]
279-
pub(super) fn structurally_resolve(
280-
&mut self,
281-
ty: Ty<'tcx>,
282-
location: impl NormalizeLocation,
283-
) -> Ty<'tcx> {
284-
if self.infcx.next_trait_solver() {
285-
let body = self.body;
286-
let param_env = self.infcx.param_env;
287-
// FIXME: Make this into a real type op?
288-
self.fully_perform_op(
289-
location.to_locations(),
290-
ConstraintCategory::Boring,
291-
CustomTypeOp::new(
292-
|ocx| {
293-
ocx.structurally_normalize_ty(
294-
&ObligationCause::misc(
295-
location.to_locations().span(body),
296-
body.source.def_id().expect_local(),
297-
),
298-
param_env,
299-
Unnormalized::new_wip(ty),
300-
)
301-
.map_err(|_| NoSolution)
302-
},
303-
"normalizing struct tail",
304-
),
305-
)
306-
.unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar))
307-
} else {
308-
self.normalize(ty, location)
309-
}
243+
let mut normalize = |ty| self.normalize(ty, location);
244+
let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {});
245+
normalize(tail)
310246
}
311247

312248
#[instrument(skip(self), level = "debug")]

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
461461
let projected_ty = curr_projected_ty.projection_ty_core(
462462
tcx,
463463
proj,
464-
|ty| self.structurally_resolve(ty, locations),
464+
|ty| self.normalize(ty, locations),
465465
|ty, variant_index, field, ()| PlaceTy::field_ty(tcx, ty, variant_index, field),
466466
|_| unreachable!(),
467467
);

compiler/rustc_hir_analysis/src/autoderef.rs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,7 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> {
8787
let (kind, new_ty) =
8888
if let Some(ty) = self.state.cur_ty.builtin_deref(self.include_raw_pointers) {
8989
debug_assert_eq!(ty, self.infcx.resolve_vars_if_possible(ty));
90-
// NOTE: we may still need to normalize the built-in deref in case
91-
// we have some type like `&<Ty as Trait>::Assoc`, since users of
92-
// autoderef expect this type to have been structurally normalized.
93-
if self.infcx.next_trait_solver()
94-
&& let ty::Alias(..) = ty.kind()
95-
{
96-
let (normalized_ty, obligations) =
97-
self.structurally_normalize_ty(Unnormalized::new_wip(ty))?;
98-
self.state.obligations.extend(obligations);
99-
(AutoderefKind::Builtin, normalized_ty)
100-
} else {
101-
(AutoderefKind::Builtin, ty)
102-
}
90+
(AutoderefKind::Builtin, ty)
10391
} else if let Some(ty) = self.overloaded_deref_ty(self.state.cur_ty) {
10492
// The overloaded deref check already normalizes the pointee type.
10593
(AutoderefKind::Overloaded, ty)
@@ -177,35 +165,27 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
177165
return None;
178166
}
179167

180-
let (normalized_ty, obligations) = self.structurally_normalize_ty(Unnormalized::new(
181-
Ty::new_projection(tcx, trait_target_def_id, [ty]),
182-
))?;
168+
let (normalized_ty, obligations) = self
169+
.normalize_ty(Unnormalized::new(Ty::new_projection(tcx, trait_target_def_id, [ty])))?;
183170
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
184171
self.state.obligations.extend(obligations);
185172

186173
Some(self.infcx.resolve_vars_if_possible(normalized_ty))
187174
}
188175

189176
#[instrument(level = "debug", skip(self), ret)]
190-
pub fn structurally_normalize_ty(
177+
pub fn normalize_ty(
191178
&self,
192179
ty: Unnormalized<'tcx, Ty<'tcx>>,
193180
) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> {
194181
let ocx = ObligationCtxt::new(self.infcx);
195-
let Ok(normalized_ty) = ocx.structurally_normalize_ty(
182+
let normalized_ty = ocx.normalize(
196183
&traits::ObligationCause::misc(self.span, self.body_id),
197184
self.param_env,
198185
ty,
199-
) else {
200-
// We shouldn't have errors here in the old solver, except for
201-
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
202-
return None;
203-
};
186+
);
204187
let errors = ocx.try_evaluate_obligations();
205188
if !errors.is_empty() {
206-
if self.infcx.next_trait_solver() {
207-
unreachable!();
208-
}
209189
// We shouldn't have errors here in the old solver, except for
210190
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
211191
debug!(?errors, "encountered errors while fulfilling");

compiler/rustc_hir_analysis/src/coherence/orphan.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,6 @@ fn orphan_check<'tcx>(
315315
return Ok(user_ty);
316316
}
317317

318-
let ty = if infcx.next_trait_solver() {
319-
ocx.structurally_normalize_ty(
320-
&cause,
321-
ty::ParamEnv::empty(),
322-
Unnormalized::new_wip(infcx.resolve_vars_if_possible(ty)),
323-
)
324-
.unwrap_or(ty)
325-
} else {
326-
ty
327-
};
328-
329318
Ok::<_, !>(ty)
330319
};
331320

compiler/rustc_hir_typeck/src/_match.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6060
// type in that case)
6161
let mut all_arms_diverge = Diverges::WarnedAlways;
6262

63-
let expected =
64-
orig_expected.try_structurally_resolve_and_adjust_for_branches(self, expr.span);
63+
let expected = orig_expected.try_structurally_resolve_and_adjust_for_branches(self);
6564
debug!(?expected);
6665

6766
let mut coercion = {

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7979
_ => self.check_expr(callee_expr),
8080
};
8181

82-
let expr_ty = self.try_structurally_resolve_type(call_expr.span, original_callee_ty);
82+
let expr_ty = self.resolve_vars_with_obligations(original_callee_ty);
8383

8484
let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
8585
let mut result = None;
@@ -211,8 +211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
211211
arg_exprs: &'tcx [hir::Expr<'tcx>],
212212
autoderef: &Autoderef<'a, 'tcx>,
213213
) -> Option<CallStep<'tcx>> {
214-
let adjusted_ty =
215-
self.try_structurally_resolve_type(autoderef.span(), autoderef.final_ty());
214+
let adjusted_ty = self.resolve_vars_with_obligations(autoderef.final_ty());
216215

217216
// If the callee is a function pointer or a closure, then we're all set.
218217
match *adjusted_ty.kind() {

compiler/rustc_hir_typeck/src/cast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
102102
return Ok(Some(PointerKind::Thin));
103103
}
104104

105-
let t = self.try_structurally_resolve_type(span, t);
105+
let t = self.resolve_vars_with_obligations(t);
106106

107107
Ok(match *t.kind() {
108108
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
@@ -1041,8 +1041,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
10411041
mut m_cast: ty::TypeAndMut<'tcx>,
10421042
) -> Result<CastKind, CastError<'tcx>> {
10431043
// array-ptr-cast: allow mut-to-mut, mut-to-const, const-to-const
1044-
m_expr.ty = fcx.try_structurally_resolve_type(self.expr_span, m_expr.ty);
1045-
m_cast.ty = fcx.try_structurally_resolve_type(self.cast_span, m_cast.ty);
1044+
m_expr.ty = fcx.resolve_vars_with_obligations(m_expr.ty);
1045+
m_cast.ty = fcx.resolve_vars_with_obligations(m_cast.ty);
10461046

10471047
if m_expr.mutbl >= m_cast.mutbl
10481048
&& let ty::Array(ety, _) = m_expr.ty.kind()

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5959
// closure sooner rather than later, so first examine the expected
6060
// type, and see if can glean a closure kind from there.
6161
let (expected_sig, expected_kind) = match expected.to_option(self) {
62-
Some(ty) => self.deduce_closure_signature(
63-
self.try_structurally_resolve_type(expr_span, ty),
64-
closure.kind,
65-
),
62+
Some(ty) => {
63+
self.deduce_closure_signature(self.resolve_vars_with_obligations(ty), closure.kind)
64+
}
6665
None => (None, None),
6766
};
6867

@@ -963,7 +962,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
963962

964963
let closure_span = self.tcx.def_span(body_def_id);
965964
let ret_ty = ret_coercion.borrow().expected_ty();
966-
let ret_ty = self.try_structurally_resolve_type(closure_span, ret_ty);
965+
let ret_ty = self.resolve_vars_with_obligations(ret_ty);
967966

968967
let get_future_output = |predicate: ty::Predicate<'tcx>, span| {
969968
// Search for a pending obligation like

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,17 +1051,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10511051
&self,
10521052
expr: &'tcx hir::Expr<'tcx>,
10531053
expr_ty: Ty<'tcx>,
1054-
mut target: Ty<'tcx>,
1054+
target: Ty<'tcx>,
10551055
allow_two_phase: AllowTwoPhase,
10561056
cause: Option<ObligationCause<'tcx>>,
10571057
) -> RelateResult<'tcx, Ty<'tcx>> {
1058-
let source = self.try_structurally_resolve_type(expr.span, expr_ty);
1059-
if self.next_trait_solver() {
1060-
target = self.try_structurally_resolve_type(
1061-
cause.as_ref().map_or(expr.span, |cause| cause.span),
1062-
target,
1063-
);
1064-
}
1058+
let source = self.resolve_vars_with_obligations(expr_ty);
10651059
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
10661060

10671061
let cause =
@@ -1099,23 +1093,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10991093
// Make sure to structurally resolve the types, since we use
11001094
// the `TyKind`s heavily in coercion.
11011095
let ocx = ObligationCtxt::new(self);
1102-
let structurally_resolve = |ty| {
1103-
let ty = self.shallow_resolve(ty);
1104-
if self.next_trait_solver()
1105-
&& let ty::Alias(..) = ty.kind()
1106-
{
1107-
ocx.structurally_normalize_ty(&cause, self.param_env, Unnormalized::new_wip(ty))
1108-
} else {
1109-
Ok(ty)
1110-
}
1111-
};
1112-
let Ok(expr_ty) = structurally_resolve(expr_ty) else {
1113-
return false;
1114-
};
1115-
let Ok(target_ty) = structurally_resolve(target_ty) else {
1116-
return false;
1117-
};
1118-
11191096
let Ok(ok) = coerce.coerce(expr_ty, target_ty) else {
11201097
return false;
11211098
};
@@ -1261,8 +1238,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12611238
new: &hir::Expr<'_>,
12621239
new_ty: Ty<'tcx>,
12631240
) -> RelateResult<'tcx, Ty<'tcx>> {
1264-
let prev_ty = self.try_structurally_resolve_type(cause.span, prev_ty);
1265-
let new_ty = self.try_structurally_resolve_type(new.span, new_ty);
1241+
let prev_ty = self.resolve_vars_with_obligations(prev_ty);
1242+
let new_ty = self.resolve_vars_with_obligations(new_ty);
12661243
debug!(
12671244
"coercion::try_find_coercion_lub({:?}, {:?}, exprs={:?} exprs)",
12681245
prev_ty,

compiler/rustc_hir_typeck/src/demand.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
260260
mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
261261
allow_two_phase: AllowTwoPhase,
262262
) -> Result<Ty<'tcx>, Diag<'a>> {
263-
let expected = if self.next_trait_solver() {
264-
expected
265-
} else {
266-
self.resolve_vars_with_obligations(expected)
267-
};
263+
let expected = self.resolve_vars_with_obligations(expected);
268264

269265
let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {
270266
Ok(ty) => return Ok(ty),

0 commit comments

Comments
 (0)