Skip to content

Commit e22c616

Browse files
committed
Auto merge of #155083 - adwinwhite:introduce-unnormalized, r=lcnr
Introduce `Unnormalized` wrapper This is the first step of the [eager normalization](https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/Eager.20normalization.2C.20ahoy.21/with/582996293) series. This PR introduce an `Unnormalized` wrapper and make most normalization routines consume it. The purpose is to make normalization explicit. This PR contains no behavior change. API changes are in the first two commit. There're some normalization routines left untouched: - `normalize` in the type checker of borrowck: better do it together with `field.ty()` returning `Unnormalized`. - `normalize_with_depth`: only used inside the old solver. Can be done later. - `query_normalize`: rarely used. - misc local normalization helpers. The compiler errors are mostly fixed via `ast-grep`, with exceptions handled manually.
2 parents 38799a3 + 6279106 commit e22c616

337 files changed

Lines changed: 2623 additions & 1461 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/diagnostics/bound_region_errors.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_infer::traits::query::{
1414
};
1515
use rustc_middle::ty::error::TypeError;
1616
use rustc_middle::ty::{
17-
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex,
17+
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, Unnormalized,
1818
};
1919
use rustc_span::Span;
2020
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -275,7 +275,7 @@ where
275275
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
276276
// test. Check after #85499 lands to see if its fixes have erased this difference.
277277
let ty::ParamEnvAnd { param_env, value } = key;
278-
let _ = ocx.normalize(&cause, param_env, value.value);
278+
let _ = ocx.normalize(&cause, param_env, Unnormalized::new_wip(value.value));
279279

280280
let diag = try_extract_error_from_fulfill_cx(
281281
&ocx,
@@ -322,7 +322,7 @@ where
322322
let ocx = ObligationCtxt::new(&infcx);
323323

324324
let ty::ParamEnvAnd { param_env, value } = key;
325-
let _ = ocx.deeply_normalize(&cause, param_env, value.value);
325+
let _ = ocx.deeply_normalize(&cause, param_env, Unnormalized::new_wip(value.value));
326326

327327
let diag = try_extract_error_from_fulfill_cx(
328328
&ocx,

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -754,19 +754,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
754754
}
755755

756756
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
757-
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
757+
clauses.instantiate(tcx, new_args).predicates.iter().all(|clause| {
758758
// Normalize before testing to see through type aliases and projections.
759-
if let Ok(normalized) = tcx.try_normalize_erasing_regions(
760-
self.infcx.typing_env(self.infcx.param_env),
761-
clause,
762-
) {
763-
clause = normalized;
764-
}
759+
let normalized = tcx
760+
.try_normalize_erasing_regions(
761+
self.infcx.typing_env(self.infcx.param_env),
762+
*clause,
763+
)
764+
.unwrap_or_else(|_| clause.skip_norm_wip());
765765
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
766766
tcx,
767767
ObligationCause::dummy(),
768768
self.infcx.param_env,
769-
clause,
769+
normalized,
770770
))
771771
})
772772
}) {
@@ -4222,11 +4222,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
42224222
if is_closure {
42234223
None
42244224
} else {
4225-
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
4225+
let ty = self
4226+
.infcx
4227+
.tcx
4228+
.type_of(self.mir_def_id())
4229+
.instantiate_identity()
4230+
.skip_norm_wip();
42264231
match ty.kind() {
42274232
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
42284233
self.mir_def_id(),
4229-
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
4234+
self.infcx
4235+
.tcx
4236+
.fn_sig(self.mir_def_id())
4237+
.instantiate_identity()
4238+
.skip_norm_wip(),
42304239
),
42314240
_ => None,
42324241
}

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,9 +1366,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
13661366
let parent_self_ty =
13671367
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
13681368
.then_some(parent_did)
1369-
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
1370-
ty::Adt(def, ..) => Some(def.did()),
1371-
_ => None,
1369+
.and_then(|did| {
1370+
match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
1371+
{
1372+
ty::Adt(def, ..) => Some(def.did()),
1373+
_ => None,
1374+
}
13721375
});
13731376
let is_option_or_result = parent_self_ty.is_some_and(|def_id| {
13741377
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
@@ -1445,7 +1448,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
14451448
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
14461449
fn_call_span,
14471450
BoundRegionConversionTime::FnCall,
1448-
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
1451+
tcx.fn_sig(method_did)
1452+
.instantiate(tcx, method_args)
1453+
.skip_norm_wip()
1454+
.input(0),
14491455
)
14501456
&& self.infcx.can_eq(self.infcx.param_env, ty, self_ty)
14511457
{

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
640640
// Check whether one of the where-bounds requires the closure to impl `Fn[Mut]`
641641
// or `AsyncFn[Mut]`.
642642
for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) {
643+
let pred = pred.skip_norm_wip();
643644
let dominated_by_fn_trait = self
644-
.closure_clause_kind(*pred, def_id, asyncness)
645+
.closure_clause_kind(pred, def_id, asyncness)
645646
.is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut));
646647
if dominated_by_fn_trait {
647648
// Found `<TyOfCapturingClosure as FnMut>` or

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir::def_id::DefId;
99
use rustc_middle::mir::{self, ConstraintCategory, Location};
1010
use rustc_middle::ty::{
1111
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
12+
Unnormalized,
1213
};
1314
use rustc_span::Span;
1415
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
@@ -282,6 +283,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGen
282283
.tcx
283284
.explicit_item_bounds(def_id)
284285
.iter_instantiated_copied(self.tcx, args)
286+
.map(Unnormalized::skip_norm_wip)
285287
{
286288
bound.visit_with(self)?;
287289
}

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
596596

597597
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
598598
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
599-
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity()
599+
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
600600
};
601601

602602
debug!("report_fnmut_error: output_ty={:?}", output_ty);
@@ -933,7 +933,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
933933
debug!(?fn_did, ?args);
934934

935935
// Only suggest this on function calls, not closures
936-
let ty = tcx.type_of(fn_did).instantiate_identity();
936+
let ty = tcx.type_of(fn_did).instantiate_identity().skip_norm_wip();
937937
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
938938
if let ty::Closure(_, _) = ty.kind() {
939939
return;
@@ -1053,7 +1053,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
10531053
else {
10541054
return;
10551055
};
1056-
let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind()
1056+
let ty::Closure(_, args) =
1057+
*tcx.type_of(closure_def_id).instantiate_identity().skip_norm_wip().kind()
10571058
else {
10581059
return;
10591060
};
@@ -1151,7 +1152,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11511152
let ocx = ObligationCtxt::new(&self.infcx);
11521153
ocx.register_obligations(preds.iter().map(|(pred, span)| {
11531154
trace!(?pred);
1154-
Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred)
1155+
Obligation::misc(
1156+
tcx,
1157+
span,
1158+
self.mir_def_id(),
1159+
self.infcx.param_env,
1160+
pred.skip_norm_wip(),
1161+
)
11551162
}));
11561163

11571164
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
66
use rustc_hir as hir;
77
use rustc_hir::def::{DefKind, Res};
88
use rustc_middle::ty::print::RegionHighlightMode;
9-
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty};
9+
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty, Unnormalized};
1010
use rustc_middle::{bug, span_bug};
1111
use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym};
1212
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -418,7 +418,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
418418

419419
// Get the parent fn's signature with liberated late-bound regions,
420420
// so we have `ReLateParam` instead of `ReBound`.
421-
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity();
421+
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip();
422422
let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig);
423423
let parent_param_ty = *liberated_sig.inputs().get(param_index)?;
424424

@@ -1023,10 +1023,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
10231023
return None;
10241024
};
10251025

1026-
let found = tcx
1027-
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
1028-
r.kind() == ty::ReEarlyParam(region)
1029-
});
1026+
let found = tcx.any_free_region_meets(
1027+
&tcx.type_of(region_parent).instantiate_identity().skip_norm_wip(),
1028+
|r| r.kind() == ty::ReEarlyParam(region),
1029+
);
10301030

10311031
Some(RegionName {
10321032
name: self.synthesize_region_name(),
@@ -1051,12 +1051,15 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
10511051
return None;
10521052
};
10531053

1054-
let predicates = self
1054+
let predicates: Vec<_> = self
10551055
.infcx
10561056
.tcx
10571057
.predicates_of(self.body.source.def_id())
10581058
.instantiate_identity(self.infcx.tcx)
1059-
.predicates;
1059+
.predicates
1060+
.into_iter()
1061+
.map(Unnormalized::skip_norm_wip)
1062+
.collect();
10601063

10611064
if let Some(upvar_index) = self
10621065
.regioncx

compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::mir::{Body, ConstraintCategory};
1212
use rustc_middle::ty::{
1313
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
1414
GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt,
15-
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions,
15+
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions,
1616
};
1717
use rustc_mir_dataflow::points::DenseLocationMap;
1818
use rustc_span::Span;
@@ -569,16 +569,17 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
569569
};
570570

571571
// We erase all non-member region of the opaque and need to treat these as existentials.
572-
let expected_ty =
573-
ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| {
574-
match re.kind() {
575-
ty::ReErased => infcx.next_nll_region_var(
576-
NllRegionVariableOrigin::Existential { name: None },
577-
|| crate::RegionCtxt::Existential(None),
578-
),
579-
_ => re,
580-
}
581-
});
572+
let expected_ty = ty::fold_regions(
573+
tcx,
574+
expected.ty.instantiate(tcx, key.args).skip_norm_wip(),
575+
|re, _dbi| match re.kind() {
576+
ty::ReErased => infcx.next_nll_region_var(
577+
NllRegionVariableOrigin::Existential { name: None },
578+
|| crate::RegionCtxt::Existential(None),
579+
),
580+
_ => re,
581+
},
582+
);
582583

583584
// We now simply equate the expected with the actual hidden type.
584585
let locations = Locations::All(hidden_type.span);
@@ -598,8 +599,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
598599
body.source.def_id().expect_local(),
599600
);
600601
// We need to normalize both types in the old solver before equatingt them.
601-
let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty);
602-
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty);
602+
let actual_ty = ocx.normalize(
603+
&cause,
604+
infcx.param_env,
605+
Unnormalized::new_wip(hidden_type.ty),
606+
);
607+
let expected_ty =
608+
ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty));
603609
ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
604610
},
605611
"equating opaque types",

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_infer::infer::canonical::Canonical;
55
use rustc_infer::infer::outlives::env::RegionBoundPairs;
66
use rustc_middle::bug;
77
use rustc_middle::mir::{Body, ConstraintCategory};
8-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
8+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast};
99
use rustc_span::Span;
1010
use rustc_span::def_id::DefId;
1111
use rustc_trait_selection::solve::NoSolution;
@@ -189,7 +189,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
189189
where
190190
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
191191
{
192-
self.normalize_with_category(value, location, ConstraintCategory::Boring)
192+
self.normalize_with_category(
193+
Unnormalized::new_wip(value),
194+
location,
195+
ConstraintCategory::Boring,
196+
)
193197
}
194198

195199
pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
@@ -207,13 +211,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
207211
#[instrument(skip(self), level = "debug")]
208212
pub(super) fn normalize_with_category<T>(
209213
&mut self,
210-
value: T,
214+
value: Unnormalized<'tcx, T>,
211215
location: impl NormalizeLocation,
212216
category: ConstraintCategory<'tcx>,
213217
) -> T
214218
where
215219
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
216220
{
221+
let value = value.skip_normalization();
217222
let param_env = self.infcx.param_env;
218223
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
219224
location.to_locations(),
@@ -246,11 +251,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
246251
CustomTypeOp::new(
247252
|ocx| {
248253
let structurally_normalize = |ty| {
249-
ocx.structurally_normalize_ty(
250-
&cause,
251-
param_env,
252-
ty,
253-
)
254+
ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty))
254255
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
255256
};
256257

@@ -295,7 +296,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
295296
body.source.def_id().expect_local(),
296297
),
297298
param_env,
298-
ty,
299+
Unnormalized::new_wip(ty),
299300
)
300301
.map_err(|_| NoSolution)
301302
},
@@ -364,7 +365,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
364365
// obligation for the unnormalized user_ty here. This is
365366
// where the "incorrectly skips the WF checks we normally do"
366367
// happens
367-
let user_ty = ocx.normalize(&cause, param_env, user_ty);
368+
let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty));
368369
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
369370
Ok(())
370371
},

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
17591759
);
17601760
}
17611761
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
1762-
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
1762+
let unnormalized_ty =
1763+
tcx.type_of(static_def_id).instantiate_identity().skip_norm_wip();
17631764
let normalized_ty = self.normalize(unnormalized_ty, locations);
17641765
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
17651766

0 commit comments

Comments
 (0)