diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index a927c30fae325..b9bf0475e14ea 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::query::{ }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ - self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, + self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, Unnormalized, }; use rustc_span::Span; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -275,7 +275,7 @@ where // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` // test. Check after #85499 lands to see if its fixes have erased this difference. let ty::ParamEnvAnd { param_env, value } = key; - let _ = ocx.normalize(&cause, param_env, value.value); + let _ = ocx.normalize(&cause, param_env, Unnormalized::new_wip(value.value)); let diag = try_extract_error_from_fulfill_cx( &ocx, @@ -322,7 +322,7 @@ where let ocx = ObligationCtxt::new(&infcx); let ty::ParamEnvAnd { param_env, value } = key; - let _ = ocx.deeply_normalize(&cause, param_env, value.value); + let _ = ocx.deeply_normalize(&cause, param_env, Unnormalized::new_wip(value.value)); let diag = try_extract_error_from_fulfill_cx( &ocx, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index ffe5e15c48ec1..b0afc32dc665f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -754,19 +754,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } // Test the callee's predicates, substituting in `ref_ty` for the moved argument type. - clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| { + clauses.instantiate(tcx, new_args).predicates.iter().all(|clause| { // Normalize before testing to see through type aliases and projections. - if let Ok(normalized) = tcx.try_normalize_erasing_regions( - self.infcx.typing_env(self.infcx.param_env), - clause, - ) { - clause = normalized; - } + let normalized = tcx + .try_normalize_erasing_regions( + self.infcx.typing_env(self.infcx.param_env), + clause.clone(), + ) + .unwrap_or_else(|_| clause.skip_norm_wip()); self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( tcx, ObligationCause::dummy(), self.infcx.param_env, - clause, + normalized, )) }) }) { @@ -4171,11 +4171,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if is_closure { None } else { - let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity(); + let ty = self + .infcx + .tcx + .type_of(self.mir_def_id()) + .instantiate_identity() + .skip_norm_wip(); match ty.kind() { ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig( self.mir_def_id(), - self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(), + self.infcx + .tcx + .fn_sig(self.mir_def_id()) + .instantiate_identity() + .skip_norm_wip(), ), _ => None, } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 86d7119639a3f..a9697950e38be 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1366,9 +1366,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let parent_self_ty = matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) .then_some(parent_did) - .and_then(|did| match tcx.type_of(did).instantiate_identity().kind() { - ty::Adt(def, ..) => Some(def.did()), - _ => None, + .and_then(|did| { + match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind() + { + ty::Adt(def, ..) => Some(def.did()), + _ => None, + } }); let is_option_or_result = parent_self_ty.is_some_and(|def_id| { matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result)) @@ -1445,7 +1448,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { && let self_ty = self.infcx.instantiate_binder_with_fresh_vars( fn_call_span, BoundRegionConversionTime::FnCall, - tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0), + tcx.fn_sig(method_did) + .instantiate(tcx, method_args) + .skip_norm_wip() + .input(0), ) && self.infcx.can_eq(self.infcx.param_env, ty, self_ty) { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 89e008f06ebc8..e7794c2db14a6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -640,8 +640,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Check whether one of the where-bounds requires the closure to impl `Fn[Mut]` // or `AsyncFn[Mut]`. for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) { + let pred = pred.skip_norm_wip(); let dominated_by_fn_trait = self - .closure_clause_kind(*pred, def_id, asyncness) + .closure_clause_kind(pred, def_id, asyncness) .is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut)); if dominated_by_fn_trait { // Found `` or diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs index 94767ebdd693a..259330611c483 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs @@ -9,6 +9,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::{self, ConstraintCategory, Location}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + Unnormalized, }; use rustc_span::Span; use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic; @@ -282,6 +283,7 @@ impl<'tcx> TypeVisitor> for CheckExplicitRegionMentionAndCollectGen .tcx .explicit_item_bounds(def_id) .iter_instantiated_copied(self.tcx, args) + .map(Unnormalized::skip_norm_wip) { bound.visit_with(self)?; } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index f6a20e41742bb..d647c3a8f8560 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -595,7 +595,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() { - output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity() + output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip() }; debug!("report_fnmut_error: output_ty={:?}", output_ty); @@ -930,7 +930,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!(?fn_did, ?args); // Only suggest this on function calls, not closures - let ty = tcx.type_of(fn_did).instantiate_identity(); + let ty = tcx.type_of(fn_did).instantiate_identity().skip_norm_wip(); debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); if let ty::Closure(_, _) = ty.kind() { return; @@ -1050,7 +1050,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { else { return; }; - let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind() + let ty::Closure(_, args) = + *tcx.type_of(closure_def_id).instantiate_identity().skip_norm_wip().kind() else { return; }; @@ -1148,7 +1149,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let ocx = ObligationCtxt::new(&self.infcx); ocx.register_obligations(preds.iter().map(|(pred, span)| { trace!(?pred); - Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred) + Obligation::misc( + tcx, + span, + self.mir_def_id(), + self.infcx.param_env, + pred.skip_norm_wip(), + ) })); if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 9f65052643e5a..c82d114f91857 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -6,7 +6,7 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; -use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty}; +use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -418,7 +418,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { // Get the parent fn's signature with liberated late-bound regions, // so we have `ReLateParam` instead of `ReBound`. - let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity(); + let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip(); let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig); let parent_param_ty = *liberated_sig.inputs().get(param_index)?; @@ -1023,10 +1023,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { return None; }; - let found = tcx - .any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| { - r.kind() == ty::ReEarlyParam(region) - }); + let found = tcx.any_free_region_meets( + &tcx.type_of(region_parent).instantiate_identity().skip_norm_wip(), + |r| r.kind() == ty::ReEarlyParam(region), + ); Some(RegionName { name: self.synthesize_region_name(), @@ -1051,12 +1051,15 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { return None; }; - let predicates = self + let predicates: Vec<_> = self .infcx .tcx .predicates_of(self.body.source.def_id()) .instantiate_identity(self.infcx.tcx) - .predicates; + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); if let Some(upvar_index) = self .regioncx diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index a0e7c305758dd..49b3e75b25e39 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, - TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions, + TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions, }; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; @@ -569,16 +569,17 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( }; // We erase all non-member region of the opaque and need to treat these as existentials. - let expected_ty = - ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| { - match re.kind() { - ty::ReErased => infcx.next_nll_region_var( - NllRegionVariableOrigin::Existential { name: None }, - || crate::RegionCtxt::Existential(None), - ), - _ => re, - } - }); + let expected_ty = ty::fold_regions( + tcx, + expected.ty.instantiate(tcx, key.args).skip_norm_wip(), + |re, _dbi| match re.kind() { + ty::ReErased => infcx.next_nll_region_var( + NllRegionVariableOrigin::Existential { name: None }, + || crate::RegionCtxt::Existential(None), + ), + _ => re, + }, + ); // We now simply equate the expected with the actual hidden type. let locations = Locations::All(hidden_type.span); @@ -598,8 +599,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( body.source.def_id().expect_local(), ); // We need to normalize both types in the old solver before equatingt them. - let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty); - let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty); + let actual_ty = ocx.normalize( + &cause, + infcx.param_env, + Unnormalized::new_wip(hidden_type.ty), + ); + let expected_ty = + ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty)); ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution) }, "equating opaque types", diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 21ea2c70fbb33..52373aad9085a 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_middle::bug; use rustc_middle::mir::{Body, ConstraintCategory}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast}; use rustc_span::Span; use rustc_span::def_id::DefId; use rustc_trait_selection::solve::NoSolution; @@ -189,7 +189,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { where T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, { - self.normalize_with_category(value, location, ConstraintCategory::Boring) + self.normalize_with_category( + Unnormalized::new_wip(value), + location, + ConstraintCategory::Boring, + ) } pub(super) fn deeply_normalize(&mut self, value: T, location: impl NormalizeLocation) -> T @@ -207,13 +211,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(super) fn normalize_with_category( &mut self, - value: T, + value: Unnormalized<'tcx, T>, location: impl NormalizeLocation, category: ConstraintCategory<'tcx>, ) -> T where T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, { + let value = value.inside_norm(); let param_env = self.infcx.param_env; let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( location.to_locations(), @@ -246,11 +251,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CustomTypeOp::new( |ocx| { let structurally_normalize = |ty| { - ocx.structurally_normalize_ty( - &cause, - param_env, - ty, - ) + ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty)) .unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR")) }; @@ -295,7 +296,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body.source.def_id().expect_local(), ), param_env, - ty, + Unnormalized::new_wip(ty), ) .map_err(|_| NoSolution) }, @@ -364,7 +365,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // obligation for the unnormalized user_ty here. This is // where the "incorrectly skips the WF checks we normally do" // happens - let user_ty = ocx.normalize(&cause, param_env, user_ty); + let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty)); ocx.eq(&cause, param_env, user_ty, mir_ty)?; Ok(()) }, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0b7b4e01e7523..9c7bdc3448052 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1759,7 +1759,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } } else if let Some(static_def_id) = constant.check_static_ptr(tcx) { - let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); + let unnormalized_ty = + tcx.type_of(static_def_id).instantiate_identity().skip_norm_wip(); let normalized_ty = self.normalize(unnormalized_ty, locations); let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index e96c6c7c56f9b..d057b67087c7b 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -585,7 +585,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { - let defining_ty = tcx.type_of(self.mir_def).instantiate_identity(); + let defining_ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip(); debug!("defining_ty (pre-replacement): {:?}", defining_ty); @@ -780,7 +780,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::FnDef(def_id, _) => { - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let sig = indices.fold_to_region_vids(tcx, sig); let inputs_and_output = sig.inputs_and_output(); @@ -804,7 +804,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { .infcx .tcx .type_of(va_list_did) - .instantiate(self.infcx.tcx, &[region.into()]); + .instantiate(self.infcx.tcx, &[region.into()]) + .skip_norm_wip(); // The signature needs to follow the order [input_tys, va_list_ty, output_ty] return inputs_and_output.map_bound(|tys| { @@ -822,7 +823,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // For a constant body, there are no inputs, and one // "output" (the type of the constant). assert_eq!(self.mir_def.to_def_id(), def_id); - let ty = tcx.type_of(self.mir_def).instantiate_identity(); + let ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip(); let ty = indices.fold_to_region_vids(tcx, ty); ty::Binder::dummy(tcx.mk_type_list(&[ty])) @@ -834,9 +835,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { ty::Binder::dummy(tcx.mk_type_list(&[ty])) } - DefiningTy::GlobalAsm(def_id) => { - ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) - } + DefiningTy::GlobalAsm(def_id) => ty::Binder::dummy( + tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity().skip_norm_wip()]), + ), }; // FIXME(#129952): We probably want a more principled approach here. @@ -974,7 +975,7 @@ fn for_each_late_bound_region_in_item<'tcx>( // only deduced that a param in the closure signature is late-bound from a constraint // that we discover during typeck. DefKind::Closure => { - let ty = tcx.type_of(mir_def_id).instantiate_identity(); + let ty = tcx.type_of(mir_def_id).instantiate_identity().skip_norm_wip(); match *ty.kind() { ty::Closure(_, args) => args.as_closure().sig().bound_vars(), ty::CoroutineClosure(_, args) => { diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 756f86a7d0111..6ab5c5088e55a 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -19,6 +19,7 @@ use indexmap::IndexSet; use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; +use rustc_middle::ty::Unnormalized; use rustc_session::Session; use rustc_session::config::DebugInfo; use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId}; @@ -244,7 +245,10 @@ impl DebugContext { type_names::push_generic_args( tcx, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args), + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(args), + ), &mut name, ); diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index c3e4bf1f0c275..dd776f9cfcaee 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -1,6 +1,6 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_hir::LangItem; -use rustc_middle::ty::{AssocTag, GenericArg}; +use rustc_middle::ty::{AssocTag, GenericArg, Unnormalized}; use rustc_session::config::EntryFnType; use rustc_span::{DUMMY_SP, Ident}; @@ -50,7 +50,7 @@ pub(crate) fn maybe_create_entry_wrapper( // listing. let main_ret_ty = tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - main_ret_ty.no_bound_vars().unwrap(), + Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()), ); let cmain_sig = Signature { diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 4ca890fee1918..6fd19c4f82c37 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -16,7 +16,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; use rustc_hir as hir; use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::HasTyCtxt; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, Unnormalized}; use rustc_span::{Span, Symbol, sym}; use crate::builder::Builder; @@ -539,7 +539,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *in_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(ty), + ) }); require!( metadata.is_unit(), @@ -553,7 +556,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( match *out_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) + bx.tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(ty), + ) }); require!( metadata.is_unit(), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index c91d3ec63a028..2f5e5666ea675 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -16,7 +16,8 @@ use rustc_middle::ty::layout::{ HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, }; use rustc_middle::ty::{ - self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, + self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, + Unnormalized, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene}; @@ -1234,7 +1235,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>( } }; - assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t))); + assert!( + up_var_tys + .iter() + .all(|t| t + == cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(t))) + ); let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let layout = cx.layout_of(closure_or_coroutine_ty); @@ -1418,7 +1424,9 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( let template_params: SmallVec<_> = iter::zip(args, names) .filter_map(|(kind, name)| { kind.as_type().map(|ty| { - let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); + let actual_type = cx + .tcx + .normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)); let actual_type_di_node = type_di_node(cx, actual_type); Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node)) }) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 316ec9cb73e78..9a5c3289cabd8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_middle::bug; -use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt, Unnormalized}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use crate::common::CodegenCx; @@ -50,14 +50,23 @@ pub(super) enum UniqueTypeId<'tcx> { impl<'tcx> UniqueTypeId<'tcx> { pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { - assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t)); + assert_eq!( + t, + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(t) + ) + ); UniqueTypeId::Ty(t, private::HiddenZst) } pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { assert_eq!( enum_ty, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(enum_ty) + ) ); UniqueTypeId::VariantPart(enum_ty, private::HiddenZst) } @@ -69,7 +78,10 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( enum_ty, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(enum_ty) + ) ); UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst) } @@ -81,7 +93,10 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( enum_ty, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(enum_ty) + ) ); UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst) } @@ -93,11 +108,17 @@ impl<'tcx> UniqueTypeId<'tcx> { ) -> Self { assert_eq!( self_type, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(self_type) + ) ); assert_eq!( implemented_trait, - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait) + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(implemented_trait) + ) ); UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index c3fa86f8a2ad3..af011932ad677 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -17,7 +17,7 @@ use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::IndexVec; use rustc_middle::mir; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; -use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt, Unnormalized}; use rustc_session::Session; use rustc_session::config::{self, DebugInfo}; use rustc_span::{ @@ -458,7 +458,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { type_names::push_generic_args( tcx, - tcx.normalize_erasing_regions(self.typing_env(), args), + tcx.normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(args)), &mut name, ); @@ -595,7 +595,10 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { iter::zip(args, names) .filter_map(|(kind, name)| { kind.as_type().map(|ty| { - let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); + let actual_type = cx.tcx.normalize_erasing_regions( + cx.typing_env(), + Unnormalized::new_wip(ty), + ); let actual_type_metadata = type_di_node(cx, actual_type); Some(cx.create_template_type_parameter( name.as_str(), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 0d3d682ece21f..852b71bd54a32 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -18,7 +18,9 @@ use rustc_hir::find_attr; use rustc_middle::mir::BinOp; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::offload_meta::OffloadMetadata; -use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{ + self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv, Unnormalized, +}; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC; @@ -805,9 +807,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let fn_ty = instance.ty(tcx, self.typing_env()); let fn_sig = match *fn_ty.kind() { - ty::FnDef(def_id, args) => { - tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)) - } + ty::FnDef(def_id, args) => tcx.instantiate_bound_regions_with_erased( + tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(), + ), _ => unreachable!(), }; assert!(!fn_sig.c_variadic); @@ -2938,7 +2940,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( match in_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) + bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty)) }); require!( metadata.is_unit(), @@ -2952,7 +2954,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( match out_elem.kind() { ty::RawPtr(p_ty, _) => { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { - bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) + bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty)) }); require!( metadata.is_unit(), diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 82e51dc9b0a65..50c439593c306 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -27,7 +27,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; -use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::Session; use rustc_session::config::{self, CrateType, EntryFnType}; @@ -519,9 +519,10 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // late-bound regions, since late-bound // regions must appear in the argument // listing. - let main_ret_ty = cx - .tcx() - .normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap()); + let main_ret_ty = cx.tcx().normalize_erasing_regions( + cx.typing_env(), + Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()), + ); let Some(llfn) = cx.declare_c_main(llfty) else { // FIXME: We should be smart and show a better diagnostic here. diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index d207cdca4d4bb..01f57d5ae4291 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -22,7 +22,9 @@ use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathD use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; use rustc_middle::bug; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{ + self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt, Unnormalized, +}; use smallvec::SmallVec; use crate::debuginfo::wants_c_like_enum_debuginfo; @@ -540,8 +542,10 @@ pub fn compute_debuginfo_vtable_name<'tcx>( } if let Some(trait_ref) = trait_ref { - let trait_ref = - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); + let trait_ref = tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(trait_ref), + ); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); visited.clear(); push_generic_args_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); @@ -654,7 +658,13 @@ fn push_generic_args_internal<'tcx>( output: &mut String, visited: &mut FxHashSet>, ) -> bool { - assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args)); + assert_eq!( + args, + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(args) + ) + ); let mut args = args.non_erasable_generics().peekable(); if args.peek().is_none() { return false; diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index a45f1124f0af4..3869596cce300 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -399,8 +399,9 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { ty::BoundConstness::Const } }; - let const_conditions = - ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions); + let const_conditions = const_conditions.into_iter().map(|(c, s)| { + (ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, c), s) + }); ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| { Obligation::new( tcx, diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 3f4527a8750b6..a61eca0c27740 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -66,11 +66,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn fn_sig(&self) -> PolyFnSig<'tcx> { let did = self.def_id().to_def_id(); if self.tcx.is_closure_like(did) { - let ty = self.tcx.type_of(did).instantiate_identity(); + let ty = self.tcx.type_of(did).instantiate_identity().skip_norm_wip(); let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") }; args.as_closure().sig() } else { - self.tcx.fn_sig(did).instantiate_identity() + self.tcx.fn_sig(did).instantiate_identity().skip_norm_wip() } } } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 316fc9ba5f97d..aa5697dfc9ced 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -70,7 +70,8 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>( body: &'tcx mir::Body<'tcx>, ) -> InterpResult<'tcx, R> { let tcx = *ecx.tcx; - let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?; + let layout = + ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args).skip_norm_wip())?; let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?; trace!( diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index d948b78a0bcf9..cc4f1c300f391 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -9,7 +9,7 @@ use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; use rustc_hir::def_id::DefId; use rustc_hir::find_attr; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; -use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; +use rustc_middle::ty::{self, AdtDef, Instance, Ty, Unnormalized, VariantDef}; use rustc_middle::{bug, mir, span_bug}; use rustc_target::callconv::{ArgAbi, FnAbi}; use tracing::field::Empty; @@ -219,7 +219,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Even if `ty` is normalized, the search for the unsized tail will project // to fields, which can yield non-normalized types. So we need to provide a // normalization function. - let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env, ty); + let normalize = |ty| { + self.tcx.normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(ty)) + }; ty.ptr_metadata_ty(*self.tcx, normalize) }; return interp_ok(meta_ty(caller) == meta_ty(callee)); diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 4e7c8310007b8..18464df1e03f1 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -37,7 +37,8 @@ fn alloc_caller_location<'tcx>( let loc_ty = ecx .tcx .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span)) - .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()])); + .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()])) + .skip_norm_wip(); let loc_layout = ecx.layout_of(loc_ty).unwrap(); let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 8db056ed8737d..ad958c1f282e7 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -5,7 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Variance}; +use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Unnormalized, Variance}; use rustc_trait_selection::traits::ObligationCtxt; /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. @@ -37,8 +37,8 @@ pub fn relate_types<'tcx>( let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); - let src = ocx.normalize(&cause, param_env, src); - let dest = ocx.normalize(&cause, param_env, dest); + let src = ocx.normalize(&cause, param_env, Unnormalized::new_wip(src)); + let dest = ocx.normalize(&cause, param_env, Unnormalized::new_wip(dest)); match ocx.relate(&cause, param_env, variance, src, dest) { Ok(()) => {} Err(_) => return false, diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index c839603160310..f1bca03218e07 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -149,7 +149,9 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> { ) -> Result<(), PrintError> { self.print_def_path(def_id, parent_args)?; - let ty::Coroutine(_, args) = self.tcx.type_of(def_id).instantiate_identity().kind() else { + let ty::Coroutine(_, args) = + self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() + else { // Could be `ty::Error`. return Ok(()); }; diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 1f06b1c94237d..ad0568808709c 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,7 +1,7 @@ use rustc_hir::limit::Limit; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::PredicateObligations; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::def_id::{LOCAL_CRATE, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits::ObligationCtxt; @@ -93,7 +93,8 @@ impl<'a, 'tcx> Iterator for Autoderef<'a, 'tcx> { if self.infcx.next_trait_solver() && let ty::Alias(..) = ty.kind() { - let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?; + let (normalized_ty, obligations) = + self.structurally_normalize_ty(Unnormalized::new_wip(ty))?; self.state.obligations.extend(obligations); (AutoderefKind::Builtin, normalized_ty) } else { @@ -176,8 +177,9 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { return None; } - let (normalized_ty, obligations) = - self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?; + let (normalized_ty, obligations) = self.structurally_normalize_ty( + Unnormalized::new_wip(Ty::new_projection(tcx, trait_target_def_id, [ty])), + )?; debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); self.state.obligations.extend(obligations); @@ -187,7 +189,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { #[instrument(level = "debug", skip(self), ret)] pub fn structurally_normalize_ty( &self, - ty: Ty<'tcx>, + ty: Unnormalized<'tcx, Ty<'tcx>>, ) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> { let ocx = ObligationCtxt::new(self.infcx); let Ok(normalized_ty) = ocx.structurally_normalize_ty( diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index d86bf4cc4e4f9..bdef0b57d6914 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -54,7 +54,7 @@ pub(crate) fn check_drop_impl( tcx.ensure_result().orphan_check_impl(drop_impl_did)?; - let self_ty = tcx.type_of(drop_impl_did).instantiate_identity(); + let self_ty = tcx.type_of(drop_impl_did).instantiate_identity().skip_norm_wip(); match self_ty.kind() { ty::Adt(adt_def, adt_to_impl_args) => { @@ -206,11 +206,13 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>( // reference the params from the ADT instead of from the impl which is bad UX. To resolve // this we "rename" the ADT's params to be the impl's params which should not affect behaviour. let impl_adt_ty = Ty::new_adt(tcx, tcx.adt_def(adt_def_id), adt_to_impl_args); - let adt_env = - ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); + let adt_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id)) + .instantiate(tcx, adt_to_impl_args) + .skip_norm_wip(); let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id()); - let fresh_adt_ty = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_impl_args).self_ty(); + let fresh_adt_ty = + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_impl_args).skip_norm_wip().self_ty(); ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty) .expect("equating fully generic trait ref should never fail"); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 2dcd4ed24df4b..69bc5458d1ed7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ AdtDef, BottomUpFolder, FnSig, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, fold_regions, + TypeVisitable, TypeVisitableExt, Unnormalized, fold_regions, }; use rustc_session::lint::builtin::UNINHABITED_STATIC; use rustc_target::spec::{AbiMap, AbiMapping}; @@ -145,7 +145,7 @@ fn allowed_union_or_unsafe_field<'tcx>( .lang_items() .get(LangItem::BikeshedGuaranteedNoDrop) .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span)); - let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else { + let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) else { tcx.dcx().span_delayed_bug(span, "could not normalize field type"); return true; }; @@ -200,7 +200,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { // would be enough to check this for `extern` statics, as statics with an initializer will // have UB during initialization if they are uninhabited, but there also seems to be no good // reason to allow any statics to be uninhabited. - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(def_id); let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(l) => l, @@ -247,7 +247,7 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) { return; } - if tcx.type_of(def_id).instantiate_identity().references_error() { + if tcx.type_of(def_id).instantiate_identity().skip_norm_wip().references_error() { return; } if check_opaque_for_cycles(tcx, def_id).is_err() { @@ -336,7 +336,7 @@ fn check_opaque_meets_bounds<'tcx>( // // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it // here rather than using ReErased. - let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args); + let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args).skip_norm_wip(); let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() { ty::ReErased => infcx.next_region_var(RegionVariableOrigin::Misc(span)), _ => re, @@ -345,8 +345,10 @@ fn check_opaque_meets_bounds<'tcx>( // HACK: We eagerly instantiate some bounds to report better errors for them... // This isn't necessary for correctness, since we register these bounds when // equating the opaque below, but we should clean this up in the new solver. - for (predicate, pred_span) in - tcx.explicit_item_bounds(def_id).iter_instantiated_copied(tcx, args) + for (predicate, pred_span) in tcx + .explicit_item_bounds(def_id) + .iter_instantiated_copied(tcx, args) + .map(Unnormalized::skip_norm_wip) { let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, @@ -540,7 +542,7 @@ fn sanity_check_found_hidden_type<'tcx>( // These correspond to lifetime variables that never got resolved, so we patch this up here. ty.ty = erase_re_vars(ty.ty); // Get the hidden type. - let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); + let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args).skip_norm_wip(); let hidden_ty = erase_re_vars(hidden_ty); // If the hidden types differ, emit a type mismatch diagnostic. @@ -740,7 +742,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>( fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() { - if match tcx.type_of(def_id).instantiate_identity().kind() { + if match tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() { ty::RawPtr(_, _) => false, ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args), _ => true, @@ -783,7 +785,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); res = res.and(wfcheck::check_static_item( tcx, def_id, ty, /* should_check_for_sync */ true, )); @@ -823,10 +825,9 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().associated_items(def_id); if of_trait { let impl_trait_header = tcx.impl_trait_header(def_id); - res = res.and( - tcx.ensure_result() - .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id), - ); + res = res.and(tcx.ensure_result().coherent_trait( + impl_trait_header.trait_ref.instantiate_identity().skip_norm_wip().def_id, + )); if res.is_ok() { // Checking this only makes sense if the all trait impls satisfy basic @@ -978,7 +979,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // // Changing this to normalized obligations is a breaking change: // `type Bar = [(); panic!()];` would become an error - if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty) + if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty.skip_norm_wip()) { let filtered_obligations = unnormalized_obligations.into_iter().filter(|o| { @@ -1240,7 +1241,7 @@ fn check_impl_items_against_trait<'tcx>( impl_id: LocalDefId, impl_trait_header: ty::ImplTraitHeader<'tcx>, ) { - let trait_ref = impl_trait_header.trait_ref.instantiate_identity(); + let trait_ref = impl_trait_header.trait_ref.instantiate_identity().skip_norm_wip(); // If the trait reference itself is erroneous (so the compilation is going // to fail), skip checking the items here -- the `impl_item` table in `tcx` // isn't populated for such impls. @@ -1287,7 +1288,9 @@ fn check_impl_items_against_trait<'tcx>( tcx, ty_impl_item, ty_trait_item, - tcx.impl_trait_ref(ty_impl_item.container_id(tcx)).instantiate_identity(), + tcx.impl_trait_ref(ty_impl_item.container_id(tcx)) + .instantiate_identity() + .skip_norm_wip(), ); } ty::AssocKind::Const { .. } => {} @@ -1416,7 +1419,7 @@ fn check_impl_items_against_trait<'tcx>( } fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { - let t = tcx.type_of(def_id).instantiate_identity(); + let t = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if let ty::Adt(def, args) = t.kind() && def.is_struct() { @@ -1491,7 +1494,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { #[tracing::instrument(skip(tcx), level = "debug")] fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); let ty::Adt(def, args) = ty.kind() else { return }; if !def.is_struct() { tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-struct"); @@ -1641,7 +1644,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { if first { format!( "`{}` contains a field of type `{}`", - tcx.type_of(def.did()).instantiate_identity(), + tcx.type_of(def.did()).instantiate_identity().skip_norm_wip(), ident ) } else { @@ -1662,7 +1665,7 @@ pub(super) fn check_packed_inner( def_id: DefId, stack: &mut Vec, ) -> Option> { - if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() { + if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() { if def.is_struct() || def.is_union() { if def.repr().align.is_some() { return Some(vec![(def.did(), DUMMY_SP)]); @@ -1790,7 +1793,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) ty: Ty<'tcx>, ) -> ControlFlow> { // We can encounter projections during traversal, so ensure the type is normalized. - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = + tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); match ty.kind() { ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)), ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty), @@ -2024,7 +2028,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD return; } - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if ty.references_error() { // If there is already another error, do not emit an error for not using a type parameter. return; diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index 956e68773b796..1bcdfd9f25a5b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -15,7 +15,7 @@ use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -68,26 +68,33 @@ pub(crate) fn compare_eii_function_types<'tcx>( let mut wf_tys = FxIndexSet::default(); let norm_cause = ObligationCause::misc(external_impl_span, external_impl); - let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity(); + let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity().skip_norm_wip(); let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig); debug!(?declaration_sig); let unnormalized_external_impl_sig = infcx.instantiate_binder_with_fresh_vars( external_impl_span, infer::BoundRegionConversionTime::HigherRankedType, - tcx.fn_sig(external_impl).instantiate( - tcx, - infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()), - ), + tcx.fn_sig(external_impl) + .instantiate( + tcx, + infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()), + ) + .skip_norm_wip(), + ); + let external_impl_sig = ocx.normalize( + &norm_cause, + param_env, + Unnormalized::new_wip(unnormalized_external_impl_sig), ); - let external_impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_external_impl_sig); debug!(?external_impl_sig); // Next, add all inputs and output as well-formed tys. Importantly, // we have to do this before normalization, since the normalized ty may // not contain the input parameters. See issue #87748. wf_tys.extend(declaration_sig.inputs_and_output.iter()); - let declaration_sig = ocx.normalize(&norm_cause, param_env, declaration_sig); + let declaration_sig = + ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(declaration_sig)); // We also have to add the normalized declaration // as we don't normalize during implied bounds computation. wf_tys.extend(external_impl_sig.inputs_and_output.iter()); @@ -170,7 +177,7 @@ pub(crate) fn compare_eii_statics<'tcx>( let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); - let declaration_ty = tcx.type_of(foreign_item).instantiate_identity(); + let declaration_ty = tcx.type_of(foreign_item).instantiate_identity().skip_norm_wip(); debug!(?declaration_ty); // FIXME: Copied over from compare impl items, same issue: diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 20ee6e34e5982..19de4e19dbc9d 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, - Upcast, + Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{BytePos, DUMMY_SP, Span}; @@ -40,7 +40,8 @@ pub(super) fn compare_impl_item( ) -> Result<(), ErrorGuaranteed> { let impl_item = tcx.associated_item(impl_item_def_id); let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?); - let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).instantiate_identity(); + let impl_trait_ref = + tcx.impl_trait_ref(impl_item.container_id(tcx)).instantiate_identity().skip_norm_wip(); debug!(?impl_trait_ref); match impl_item.kind { @@ -213,9 +214,16 @@ fn compare_method_predicate_entailment<'tcx>( // We then register the obligations from the impl_m and check to see // if all constraints hold. let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + let mut hybrid_preds: Vec<_> = impl_predicates + .instantiate_identity(tcx) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); hybrid_preds.extend( - trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate), + trait_m_predicates + .instantiate_own(tcx, trait_to_impl_args) + .map(|(predicate, _)| predicate.skip_norm_wip()), ); let is_conditionally_const = tcx.is_conditionally_const(impl_m.def_id); @@ -230,6 +238,7 @@ fn compare_method_predicate_entailment<'tcx>( tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args), ) .map(|(trait_ref, _)| { + let trait_ref = trait_ref.skip_norm_wip(); trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) }), ); @@ -266,10 +275,12 @@ fn compare_method_predicate_entailment<'tcx>( // definition in the context of the hybrid param-env. This makes // sure that the impl's method's where clauses are not more // restrictive than the trait's method (and the impl itself). - let impl_m_own_bounds = impl_m_predicates.instantiate_own_identity(); + let impl_m_own_bounds = + impl_m_predicates.instantiate_own_identity().map(|(c, s)| (c.skip_norm_wip(), s)); for (predicate, span) in impl_m_own_bounds { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); - let predicate = ocx.normalize(&normalize_cause, param_env, predicate); + let predicate = + ocx.normalize(&normalize_cause, param_env, Unnormalized::new_wip(predicate)); let cause = ObligationCause::new( span, @@ -290,11 +301,14 @@ fn compare_method_predicate_entailment<'tcx>( // using the hybrid param-env that we earlier augmented with the const conditions // from the impl header and trait method declaration. if is_conditionally_const { - for (const_condition, span) in - tcx.const_conditions(impl_m.def_id).instantiate_own_identity() + for (const_condition, span) in tcx + .const_conditions(impl_m.def_id) + .instantiate_own_identity() + .map(|(c, s)| (c.skip_norm_wip(), s)) { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); - let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + let const_condition = + ocx.normalize(&normalize_cause, param_env, Unnormalized::new_wip(const_condition)); let cause = ObligationCause::new( span, @@ -327,21 +341,22 @@ fn compare_method_predicate_entailment<'tcx>( let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars( impl_m_span, BoundRegionConversionTime::HigherRankedType, - tcx.fn_sig(impl_m.def_id).instantiate_identity(), + tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(), ); let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id); - let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig); + let impl_sig = + ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(unnormalized_impl_sig)); debug!(?impl_sig); - let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args); + let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip(); let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig); // Next, add all inputs and output as well-formed tys. Importantly, // we have to do this before normalization, since the normalized ty may // not contain the input parameters. See issue #87748. wf_tys.extend(trait_sig.inputs_and_output.iter()); - let trait_sig = ocx.normalize(&norm_cause, param_env, trait_sig); + let trait_sig = ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(trait_sig)); // We also have to add the normalized trait signature // as we don't normalize during implied bounds computation. wf_tys.extend(trait_sig.inputs_and_output.iter()); @@ -463,8 +478,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( ) -> Result<&'tcx DefIdMap>>, ErrorGuaranteed> { let impl_m = tcx.associated_item(impl_m_def_id.to_def_id()); let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?); - let impl_trait_ref = - tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).instantiate_identity(); + let impl_trait_ref = tcx + .impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())) + .instantiate_identity() + .skip_norm_wip(); // First, check a few of the same things as `compare_impl_method`, // just so we don't ICE during instantiation later. check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; @@ -493,7 +510,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( .instantiate_identity(tcx) .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) - .map(|(clause, _)| clause); + .map(|(clause, _)| clause.skip_norm_wip()); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = traits::normalize_param_env_or_error( tcx, @@ -510,10 +527,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // up, then we don't want to give spurious other errors that point at the RPITITs. // They're not necessary to check, though, because we already check them in // `compare_method_predicate_entailment`. - let impl_m_own_bounds = tcx.predicates_of(impl_m_def_id).instantiate_own_identity(); + let impl_m_own_bounds = tcx + .predicates_of(impl_m_def_id) + .instantiate_own_identity() + .map(|(c, s)| (c.skip_norm_wip(), s)); for (predicate, span) in impl_m_own_bounds { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); - let predicate = ocx.normalize(&normalize_cause, param_env, predicate); + let predicate = + ocx.normalize(&normalize_cause, param_env, Unnormalized::new_wip(predicate)); let cause = ObligationCause::new( span, @@ -532,11 +553,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let impl_sig = ocx.normalize( &misc_cause, param_env, - infcx.instantiate_binder_with_fresh_vars( + Unnormalized::new_wip(infcx.instantiate_binder_with_fresh_vars( return_span, BoundRegionConversionTime::HigherRankedType, - tcx.fn_sig(impl_m.def_id).instantiate_identity(), - ), + tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(), + )), ); impl_sig.error_reported()?; let impl_return_ty = impl_sig.output(); @@ -549,11 +570,12 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let unnormalized_trait_sig = tcx .liberate_late_bound_regions( impl_m.def_id, - tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args), + tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip(), ) .fold_with(&mut collector); - let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig); + let trait_sig = + ocx.normalize(&misc_cause, param_env, Unnormalized::new_wip(unnormalized_trait_sig)); trait_sig.error_reported()?; let trait_return_ty = trait_sig.output(); @@ -839,12 +861,13 @@ where .cx() .explicit_item_bounds(def_id) .iter_instantiated_copied(self.cx(), proj_args) + .map(Unnormalized::skip_norm_wip) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), self.param_env, - pred, + Unnormalized::new_wip(pred), ); self.ocx.register_obligation(traits::Obligation::new( @@ -1252,11 +1275,11 @@ fn check_region_late_boundedness<'tcx>( .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id)); let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id); - let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args); + let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args).skip_norm_wip(); let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig); let trait_m_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id); - let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args); + let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args).skip_norm_wip(); let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig); let ocx = ObligationCtxt::new(&infcx); @@ -1443,7 +1466,7 @@ fn find_region_in_predicates<'tcx>( early_bound_region: ty::Region<'tcx>, ) -> Option { for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) { - if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() { + if pred.skip_norm_wip().visit_with(&mut FindRegion(early_bound_region)).is_break() { return Some(span); } } @@ -1508,7 +1531,7 @@ fn compare_self_type<'tcx>( } ty::AssocContainer::Trait => tcx.types.self_param, }; - let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0); + let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip().input(0); let (infcx, param_env) = tcx .infer_ctxt() .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id)); @@ -2111,7 +2134,7 @@ fn compare_generic_param_kinds<'tcx>( format!( "{} const parameter of type `{}`", prefix, - tcx.type_of(param.def_id).instantiate_identity() + tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip() ) } Type { .. } => format!("{prefix} type parameter"), @@ -2227,6 +2250,7 @@ fn compare_const_predicate_entailment<'tcx>( .instantiate_own(tcx, trait_to_impl_args) .map(|(predicate, _)| predicate), ); + let hybrid_preds: Vec<_> = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip).collect(); let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = traits::normalize_param_env_or_error( @@ -2238,10 +2262,11 @@ fn compare_const_predicate_entailment<'tcx>( let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - let impl_ct_own_bounds = impl_ct_predicates.instantiate_own_identity(); + let impl_ct_own_bounds = + impl_ct_predicates.instantiate_own_identity().map(|(c, s)| (c.skip_norm_wip(), s)); for (predicate, span) in impl_ct_own_bounds { let cause = ObligationCause::misc(span, impl_ct_def_id); - let predicate = ocx.normalize(&cause, param_env, predicate); + let predicate = ocx.normalize(&cause, param_env, Unnormalized::new_wip(predicate)); let cause = ObligationCause::new(span, impl_ct_def_id, code.clone()); ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); @@ -2335,7 +2360,8 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id); let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); - let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity(); + let impl_ty_own_bounds = + impl_ty_predicates.instantiate_own_identity().map(|(c, s)| (c.skip_norm_wip(), s)); // If there are no bounds, then there are no const conditions, so no need to check that here. if impl_ty_own_bounds.len() == 0 { // Nothing to check. @@ -2351,11 +2377,16 @@ fn compare_type_predicate_entailment<'tcx>( // The predicates declared by the impl definition, the trait and the // associated type in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + let mut hybrid_preds: Vec<_> = impl_predicates + .instantiate_identity(tcx) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); hybrid_preds.extend( trait_ty_predicates .instantiate_own(tcx, trait_to_impl_args) - .map(|(predicate, _)| predicate), + .map(|(predicate, _)| predicate.skip_norm_wip()), ); debug!(?hybrid_preds); @@ -2374,6 +2405,7 @@ fn compare_type_predicate_entailment<'tcx>( tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args), ) .map(|(trait_ref, _)| { + let trait_ref = trait_ref.skip_norm_wip(); trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) }), ); @@ -2388,7 +2420,7 @@ fn compare_type_predicate_entailment<'tcx>( for (predicate, span) in impl_ty_own_bounds { let cause = ObligationCause::misc(span, impl_ty_def_id); - let predicate = ocx.normalize(&cause, param_env, predicate); + let predicate = ocx.normalize(&cause, param_env, Unnormalized::new_wip(predicate)); let cause = ObligationCause::new( span, @@ -2404,11 +2436,14 @@ fn compare_type_predicate_entailment<'tcx>( if is_conditionally_const { // Validate the const conditions of the impl associated type. - let impl_ty_own_const_conditions = - tcx.const_conditions(impl_ty.def_id).instantiate_own_identity(); + let impl_ty_own_const_conditions = tcx + .const_conditions(impl_ty.def_id) + .instantiate_own_identity() + .map(|(c, s)| (c.skip_norm_wip(), s)); for (const_condition, span) in impl_ty_own_const_conditions { let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id); - let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + let const_condition = + ocx.normalize(&normalize_cause, param_env, Unnormalized::new_wip(const_condition)); let cause = ObligationCause::new( span, @@ -2511,12 +2546,13 @@ pub(super) fn check_type_bounds<'tcx>( let mut obligations: Vec<_> = util::elaborate( tcx, - tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map( - |(concrete_ty_bound, span)| { + tcx.explicit_item_bounds(trait_ty.def_id) + .iter_instantiated_copied(tcx, rebased_args) + .map(Unnormalized::skip_norm_wip) + .map(|(concrete_ty_bound, span)| { debug!(?concrete_ty_bound); traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) - }, - ), + }), ) .collect(); @@ -2526,6 +2562,7 @@ pub(super) fn check_type_bounds<'tcx>( tcx, tcx.explicit_implied_const_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) + .map(Unnormalized::skip_norm_wip) .map(|(c, span)| { traits::Obligation::new( tcx, @@ -2544,7 +2581,11 @@ pub(super) fn check_type_bounds<'tcx>( // See . let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); for obligation in &mut obligations { - match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) { + match ocx.deeply_normalize( + &normalize_cause, + normalize_param_env, + Unnormalized::new_wip(obligation.predicate), + ) { Ok(pred) => obligation.predicate = pred, Err(e) => { return Err(infcx.err_ctxt().report_fulfillment_errors(e)); @@ -2702,7 +2743,7 @@ fn param_env_with_gat_bounds<'tcx>( // checking the default value specifically here. Add this equality to the // ParamEnv for normalization specifically. let normalize_impl_ty = - tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args); + tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args).skip_norm_wip(); let rebased_args = normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args); let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 01e8a8c4b1934..cdda54f7eb943 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, TypingMode, + TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, }; use rustc_span::Span; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -44,19 +44,22 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( let impl_def_id = impl_m.container_id(tcx); let impl_m_args = ty::GenericArgs::identity_for_item(tcx, impl_m.def_id); let trait_m_to_impl_m_args = impl_m_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args); - let bound_trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args); + let bound_trait_m_sig = + tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args).skip_norm_wip(); let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, bound_trait_m_sig); // replace the self type of the trait ref with `Self` so that diagnostics render better. let trait_m_sig_with_self_for_diag = tcx.liberate_late_bound_regions( impl_m.def_id, - tcx.fn_sig(trait_m.def_id).instantiate( - tcx, - tcx.mk_args_from_iter( - [tcx.types.self_param.into()] - .into_iter() - .chain(trait_m_to_impl_m_args.iter().skip(1)), - ), - ), + tcx.fn_sig(trait_m.def_id) + .instantiate( + tcx, + tcx.mk_args_from_iter( + [tcx.types.self_param.into()] + .into_iter() + .chain(trait_m_to_impl_m_args.iter().skip(1)), + ), + ) + .skip_norm_wip(), ); let Ok(hidden_tys) = tcx.collect_return_position_impl_trait_in_trait_tys(impl_m.def_id) else { @@ -80,8 +83,9 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( for trait_projection in collector.types.into_iter().rev() { let impl_opaque_args = trait_projection.args.rebase_onto(tcx, trait_m.def_id, impl_m_args); - let hidden_ty = - hidden_tys[&trait_projection.kind.def_id()].instantiate(tcx, impl_opaque_args); + let hidden_ty = hidden_tys[&trait_projection.kind.def_id()] + .instantiate(tcx, impl_opaque_args) + .skip_norm_wip(); // If the hidden type is not an opaque, then we have "refined" the trait signature. let ty::Alias( @@ -121,12 +125,14 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( trait_bounds.extend( tcx.item_bounds(trait_projection.kind.def_id()) - .iter_instantiated(tcx, trait_projection.args), + .iter_instantiated(tcx, trait_projection.args) + .map(Unnormalized::skip_norm_wip), ); impl_bounds.extend(elaborate( tcx, tcx.explicit_item_bounds(impl_opaque_def_id) - .iter_instantiated_copied(tcx, impl_opaque.args), + .iter_instantiated_copied(tcx, impl_opaque.args) + .map(Unnormalized::skip_norm_wip), )); pairs.push((trait_projection, impl_opaque)); @@ -137,7 +143,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( .instantiate_identity(tcx) .into_iter() .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) - .map(|(clause, _)| clause); + .map(|(clause, _)| clause.skip_norm_wip()); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy()); @@ -152,9 +158,11 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( // 2. Deeply normalize any other projections that show up in the bound. That makes sure // that we don't consider `tests/ui/async-await/in-trait/async-associated-types.rs` // or `tests/ui/impl-trait/in-trait/refine-normalize.rs` to be refining. - let Ok((trait_bounds, impl_bounds)) = - ocx.deeply_normalize(&ObligationCause::dummy(), param_env, (trait_bounds, impl_bounds)) - else { + let Ok((trait_bounds, impl_bounds)) = ocx.deeply_normalize( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip((trait_bounds, impl_bounds)), + ) else { tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); return; }; @@ -168,7 +176,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( implied_wf_types.extend(ocx.normalize( &ObligationCause::dummy(), param_env, - trait_m_sig.inputs_and_output, + Unnormalized::new_wip(trait_m_sig.inputs_and_output), )); if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); @@ -267,6 +275,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitCollector<'tcx> { .tcx .explicit_item_bounds(def_id) .iter_instantiated_copied(self.tcx, proj.args) + .map(Unnormalized::skip_norm_wip) { pred.visit_with(self); } @@ -320,6 +329,7 @@ fn report_mismatched_rpitit_signature<'tcx>( let Some(future_output_ty) = tcx .explicit_item_bounds(future_ty_def_id) .iter_instantiated_copied(tcx, args) + .map(Unnormalized::skip_norm_wip) .find_map(|(clause, _)| match clause.kind().no_bound_vars()? { ty::ClauseKind::Projection(proj) => proj.term.as_type(), _ => None, diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index 4c72f5a654e1d..e00cfe4c1bbeb 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::{Node, find_attr}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::span_bug; -use rustc_middle::ty::{self, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized}; use rustc_session::config::EntryFnType; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_span::{ErrorGuaranteed, Span}; @@ -24,12 +24,12 @@ pub(crate) fn check_for_entry_fn(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> } fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) -> Result<(), ErrorGuaranteed> { - let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity(); + let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity().skip_norm_wip(); let main_span = tcx.def_span(main_def_id); fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { if let Some(local_def_id) = def_id.as_local() { - let hir_type = tcx.type_of(local_def_id).instantiate_identity(); + let hir_type = tcx.type_of(local_def_id).instantiate_identity().skip_norm_wip(); if !matches!(hir_type.kind(), ty::FnDef(..)) { span_bug!(sp, "main has a non-function type: found `{}`", hir_type); } @@ -130,7 +130,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) -> Result<(), ErrorGuar ObligationCauseCode::MainFunctionType, ); let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); - let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); + let norm_return_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(return_ty)); ocx.register_bound(cause, param_env, norm_return_ty, term_did); let errors = ocx.evaluate_obligations_error_on_ambiguity(); if !errors.is_empty() { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 58454cfc489c6..a468c3239a2ed 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -278,7 +278,7 @@ pub(crate) fn check_intrinsic_type( kind: ty::BoundRegionKind::ClosureEnv, }, ); - let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]); + let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]).skip_norm_wip(); (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty) }; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 950696db44efb..8922e7aa976e2 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -89,6 +89,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::print::with_types_for_signature; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, OutlivesPredicate, Region, Ty, TyCtxt, TypingMode, + Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; @@ -238,7 +239,7 @@ fn missing_items_err( let snippet = with_types_for_signature!(suggestion_signature( tcx, trait_item, - tcx.impl_trait_ref(impl_def_id).instantiate_identity(), + tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip(), )); let code = format!("{padding}{snippet}\n{padding}"); if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) { @@ -489,6 +490,7 @@ fn fn_sig_suggestion<'tcx>( && let Some(output) = tcx .explicit_item_self_bounds(alias_ty.kind.def_id()) .iter_instantiated_copied(tcx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) .find_map(|(bound, _)| { bound.as_projection_clause()?.no_bound_vars()?.term.as_type() }) { @@ -536,22 +538,26 @@ fn suggestion_signature<'tcx>( tcx, tcx.liberate_late_bound_regions( assoc.def_id, - tcx.fn_sig(assoc.def_id).instantiate(tcx, args), + tcx.fn_sig(assoc.def_id).instantiate(tcx, args).skip_norm_wip(), ), assoc.ident(tcx), - tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), + tcx.predicates_of(assoc.def_id) + .instantiate_own(tcx, args) + .map(|(c, s)| (c.skip_norm_wip(), s)), assoc, ), ty::AssocKind::Type { .. } => { let (generics, where_clauses) = bounds_from_generic_predicates( tcx, - tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), + tcx.predicates_of(assoc.def_id) + .instantiate_own(tcx, args) + .map(|(c, s)| (c.skip_norm_wip(), s)), assoc, ); format!("type {}{generics} = /* Type */{where_clauses};", assoc.name()) } ty::AssocKind::Const { name, .. } => { - let ty = tcx.type_of(assoc.def_id).instantiate_identity(); + let ty = tcx.type_of(assoc.def_id).instantiate_identity().skip_norm_wip(); let val = tcx .infer_ctxt() .build(TypingMode::non_body_analysis()) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d5f17a5cbb75b..35b5781735b84 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, - Upcast, + Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; @@ -66,7 +66,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // Convenience function to normalize during wfcheck. This performs // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`. - fn normalize(&self, span: Span, loc: Option, value: T) -> T + fn normalize( + &self, + span: Span, + loc: Option, + value: Unnormalized<'tcx, T>, + ) -> T where T: TypeFoldable>, { @@ -86,7 +91,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { /// signature types for implied bounds when checking regions. // FIXME(-Znext-solver): This should be removed when we compute implied outlives // bounds using the unnormalized signature of the function we're checking. - pub(super) fn deeply_normalize(&self, span: Span, loc: Option, value: T) -> T + pub(super) fn deeply_normalize( + &self, + span: Span, + loc: Option, + value: Unnormalized<'tcx, T>, + ) -> T where T: TypeFoldable>, { @@ -99,7 +109,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { Ok(value) => value, Err(errors) => { self.infcx.err_ctxt().report_fulfillment_errors(errors); - value + value.skip_norm_wip() } } } else { @@ -416,7 +426,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from. let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions( item_def_id.to_def_id(), - tcx.fn_sig(item_def_id).instantiate_identity(), + tcx.fn_sig(item_def_id).instantiate_identity().skip_norm_wip(), ); gather_gat_bounds( tcx, @@ -446,6 +456,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { item_def_id, tcx.explicit_item_bounds(item_def_id) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .collect::>(), &FxIndexSet::default(), gat_def_id, @@ -840,7 +851,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er // Const parameters are well formed if their type is structural match. ty::GenericParamDefKind::Const { .. } => { - let ty = tcx.type_of(param.def_id).instantiate_identity(); + let ty = tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(param.def_id); let def_id = param.def_id.expect_local(); @@ -963,7 +974,7 @@ pub(crate) fn check_associated_item( let self_ty = match item.container { ty::AssocContainer::Trait => tcx.types.self_param, ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { - tcx.type_of(item.container_id(tcx)).instantiate_identity() + tcx.type_of(item.container_id(tcx)).instantiate_identity().skip_norm_wip() } }; @@ -993,7 +1004,7 @@ pub(crate) fn check_associated_item( Ok(()) } ty::AssocKind::Fn { .. } => { - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let hir_sig = tcx.hir_node_by_def_id(def_id).fn_sig().expect("bad signature for method"); check_fn_or_method(wfcx, sig, hir_sig.decl, def_id); @@ -1082,7 +1093,7 @@ fn check_type_defn<'tcx>( // intermediate types must be sized. let needs_drop_copy = || { packed && { - let ty = tcx.type_of(variant.tail().did).instantiate_identity(); + let ty = tcx.type_of(variant.tail().did).instantiate_identity().skip_norm_wip(); let ty = tcx.erase_and_anonymize_regions(ty); assert!(!ty.has_infer()); ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env)) @@ -1189,15 +1200,17 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = bounds.iter_identity_copied().flat_map(|(bound, bound_span)| { - traits::wf::clause_obligations( - wfcx.infcx, - wfcx.param_env, - wfcx.body_def_id, - bound, - bound_span, - ) - }); + let wf_obligations = bounds.iter_identity_copied().map(Unnormalized::skip_norm_wip).flat_map( + |(bound, bound_span)| { + traits::wf::clause_obligations( + wfcx.infcx, + wfcx.param_env, + wfcx.body_def_id, + bound, + bound_span, + ) + }, + ); wfcx.register_obligations(wf_obligations); } @@ -1210,7 +1223,7 @@ fn check_item_fn( enter_wf_checking_ctxt(tcx, def_id, |wfcx| { check_eiis_fn(tcx, def_id); - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); check_fn_or_method(wfcx, sig, decl, def_id); Ok(()) }) @@ -1284,14 +1297,14 @@ pub(crate) fn check_static_item<'tcx>( let span = tcx.ty_span(item_id); let loc = Some(WellFormedLoc::Ty(item_id)); - let item_ty = wfcx.deeply_normalize(span, loc, ty); + let item_ty = wfcx.deeply_normalize(span, loc, Unnormalized::new_wip(ty)); let is_foreign_item = tcx.is_foreign_item(item_id); let is_structurally_foreign_item = || { let tail = tcx.struct_tail_raw( item_ty, &ObligationCause::dummy(), - |ty| wfcx.deeply_normalize(span, loc, ty), + |ty| wfcx.deeply_normalize(span, loc, Unnormalized::new_wip(ty)), || {}, ); @@ -1383,7 +1396,7 @@ fn check_impl<'tcx>( let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity(); // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in // case other `Foo` impls are incoherent. - tcx.ensure_result().coherent_trait(trait_ref.def_id)?; + tcx.ensure_result().coherent_trait(trait_ref.probe(|v| v.def_id))?; let trait_span = of_trait.trait_ref.path.span; let trait_ref = wfcx.deeply_normalize( trait_span, @@ -1444,11 +1457,11 @@ fn check_impl<'tcx>( wfcx.register_obligations(obligations); } None => { - let self_ty = tcx.type_of(item.owner_id).instantiate_identity(); + let self_ty = tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); let self_ty = wfcx.deeply_normalize( item.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), - self_ty, + Unnormalized::new_wip(self_ty), ); wfcx.register_wf_obligation( impl_.self_ty.span, @@ -1479,7 +1492,11 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: // // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. for param in &generics.own_params { - if let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity) { + if let Some(default) = param + .default_value(tcx) + .map(ty::EarlyBinder::instantiate_identity) + .map(Unnormalized::skip_norm_wip) + { // Ignore dependent defaults -- that is, where the default of one type // parameter includes another (e.g., ``). In those cases, we can't // be sure if it will error or not as user might always specify the other. @@ -1507,14 +1524,14 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => continue, ty::ConstKind::Value(cv) => cv.ty, ty::ConstKind::Unevaluated(uv) => { - infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) + infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args).skip_norm_wip() } ty::ConstKind::Param(param_ct) => { param_ct.find_const_ty_from_env(wfcx.param_env) } }; - let param_ty = tcx.type_of(param.def_id).instantiate_identity(); + let param_ty = tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip(); if !ct_ty.has_param() && !param_ty.has_param() { let cause = traits::ObligationCause::new( tcx.def_span(param.def_id), @@ -1543,7 +1560,7 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| { if param.index >= generics.parent_count as u32 // If the param has a default, ... - && let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity) + && let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity).map(Unnormalized::skip_norm_wip) // ... and it's not a dependent default, ... && !default.has_param() { @@ -1587,12 +1604,16 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. - if instantiated_pred.has_non_region_param() + if instantiated_pred.probe(|v| v.has_non_region_param()) || param_count.params.len() > 1 || has_region { None - } else if predicates.predicates.iter().any(|&(p, _)| p == instantiated_pred) { + } else if predicates + .predicates + .iter() + .any(|&(p, _)| Unnormalized::new_wip(p) == instantiated_pred) + { // Avoid duplication of predicates that contain no parameters, for example. None } else { @@ -1626,13 +1647,15 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: .copied() .zip(predicates.spans.iter().copied()) .filter_map(|(clause, sp)| { + let clause = clause.skip_norm_wip(); let proj = clause.as_projection_clause()?; let pred_binder = proj .map_bound(|pred| { pred.term.as_const().map(|ct| { let assoc_const_ty = tcx .type_of(pred.projection_term.def_id) - .instantiate(tcx, pred.projection_term.args); + .instantiate(tcx, pred.projection_term.args) + .skip_norm_wip(); ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty) }) }) @@ -1650,7 +1673,13 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: assert_eq!(predicates.predicates.len(), predicates.spans.len()); let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { - traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) + traits::wf::clause_obligations( + infcx, + wfcx.param_env, + wfcx.body_def_id, + p.skip_norm_wip(), + sp, + ) }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect(); @@ -1685,7 +1714,7 @@ fn check_fn_or_method<'tcx>( // one greater than the index of the last input type. param_idx: idx, }), - ty, + Unnormalized::new_wip(ty), ) })); @@ -1771,16 +1800,16 @@ fn check_method_receiver<'tcx>( let span = fn_sig.decl.inputs[0].span; let loc = Some(WellFormedLoc::Param { function: method.def_id.expect_local(), param_idx: 0 }); - let sig = tcx.fn_sig(method.def_id).instantiate_identity(); + let sig = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip(); let sig = tcx.liberate_late_bound_regions(method.def_id, sig); - let sig = wfcx.normalize(DUMMY_SP, loc, sig); + let sig = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(sig)); debug!("check_method_receiver: sig={:?}", sig); - let self_ty = wfcx.normalize(DUMMY_SP, loc, self_ty); + let self_ty = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(self_ty)); let receiver_ty = sig.inputs()[0]; - let receiver_ty = wfcx.normalize(DUMMY_SP, loc, receiver_ty); + let receiver_ty = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(receiver_ty)); // If the receiver already has errors reported, consider it valid to avoid // unnecessary errors (#58712). @@ -2114,6 +2143,7 @@ pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: Loc if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx .type_of(def_id) .instantiate_identity() + .skip_norm_wip() .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) { continue; @@ -2145,7 +2175,11 @@ impl<'tcx> TypeVisitor> for HasErrorDeep<'tcx> { ty::Adt(def, _) => { if self.seen.insert(def.did()) { for field in def.all_fields() { - self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?; + self.tcx + .type_of(field.did) + .instantiate_identity() + .skip_norm_wip() + .visit_with(self)?; } } } @@ -2266,11 +2300,15 @@ impl<'tcx> IsProbablyCyclical<'tcx> { match self.tcx.def_kind(def_id) { DefKind::Struct | DefKind::Enum | DefKind::Union => { self.tcx.adt_def(def_id).all_fields().try_for_each(|field| { - self.tcx.type_of(field.did).instantiate_identity().visit_with(self) + self.tcx + .type_of(field.did) + .instantiate_identity() + .skip_norm_wip() + .visit_with(self) }) } DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => { - self.tcx.type_of(def_id).instantiate_identity().visit_with(self) + self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().visit_with(self) } _ => ControlFlow::Continue(()), } @@ -2356,7 +2394,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // Match the existing behavior. if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) { - let pred = self.normalize(span, None, pred); + let pred = self.normalize(span, None, Unnormalized::new_wip(pred)); // only use the span of the predicate clause (#90869) let hir_node = tcx.hir_node_by_def_id(self.body_def_id); @@ -2471,8 +2509,13 @@ fn lint_redundant_lifetimes<'tcx>( ); // If we are in a function, add its late-bound lifetimes too. if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) { - for (idx, var) in - tcx.fn_sig(owner_id).instantiate_identity().bound_vars().iter().enumerate() + for (idx, var) in tcx + .fn_sig(owner_id) + .instantiate_identity() + .skip_norm_wip() + .bound_vars() + .iter() + .enumerate() { let ty::BoundVariableKind::Region(kind) = var else { continue }; let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61453e5328d5f..2e31ce831a518 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -73,7 +73,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran let tcx = checker.tcx; let impl_did = checker.impl_def_id; // Destructors only work on local ADT types. - match checker.impl_header.trait_ref.instantiate_identity().self_ty().kind() { + match checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty().kind() { ty::Adt(def, _) if def.did().is_local() => return Ok(()), ty::Error(_) => return Ok(()), _ => {} @@ -93,7 +93,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran let impl_did = checker.impl_def_id; debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); + let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty(); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); let param_env = tcx.param_env(impl_did); @@ -142,7 +142,7 @@ fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuara let impl_did = checker.impl_def_id; debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did); - let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); + let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty(); debug!("visit_implementation_of_unpin: self_type={:?}", self_type); let span = tcx.def_span(impl_did); @@ -175,7 +175,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E let tcx = checker.tcx; let header = checker.impl_header; let impl_did = checker.impl_def_id; - let self_type = header.trait_ref.instantiate_identity().self_ty(); + let self_type = header.trait_ref.instantiate_identity().skip_norm_wip().self_ty(); assert!(!self_type.has_escaping_bound_vars()); let param_env = tcx.param_env(impl_did); @@ -259,7 +259,7 @@ fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool { fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; let impl_did = checker.impl_def_id; - let trait_ref = checker.impl_header.trait_ref.instantiate_identity(); + let trait_ref = checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip(); debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); @@ -348,9 +348,9 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() if tcx .try_normalize_erasing_regions( ty::TypingEnv::non_body_analysis(tcx, def_a.did()), - unnormalized_ty, + unnormalized_ty.clone(), ) - .unwrap_or(unnormalized_ty) + .unwrap_or(unnormalized_ty.skip_norm_wip()) .is_phantom_data() { return None; @@ -445,8 +445,8 @@ pub(crate) fn coerce_unsized_info<'tcx>( let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span); let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span); - let source = tcx.type_of(impl_did).instantiate_identity(); - let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity(); + let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip(); + let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.args.type_at(1); @@ -568,9 +568,9 @@ pub(crate) fn coerce_unsized_info<'tcx>( if tcx .try_normalize_erasing_regions( ty::TypingEnv::non_body_analysis(tcx, def_a.did()), - unnormalized_ty, + unnormalized_ty.clone(), ) - .unwrap_or(unnormalized_ty) + .unwrap_or(unnormalized_ty.skip_norm_wip()) .is_phantom_data() { return None; @@ -788,7 +788,8 @@ fn visit_implementation_of_coerce_pointee_validity( checker: &Checker<'_>, ) -> Result<(), ErrorGuaranteed> { let tcx = checker.tcx; - let self_ty = tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().self_ty(); + let self_ty = + tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().skip_norm_wip().self_ty(); let span = tcx.def_span(checker.impl_def_id); if !tcx.is_builtin_derived(checker.impl_def_id.into()) { return Err(tcx.dcx().emit_err(errors::CoercePointeeNoUserValidityAssertion { span })); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index b13983cf7444f..52567667b0fe6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -164,7 +164,7 @@ impl<'tcx> InherentCollect<'tcx> { let id = id.owner_id.def_id; let item_span = self.tcx.def_span(id); - let self_ty = self.tcx.type_of(id).instantiate_identity(); + let self_ty = self.tcx.type_of(id).instantiate_identity().skip_norm_wip(); let mut self_ty = self.tcx.peel_off_free_alias_tys(self_ty); // We allow impls on pattern types exactly when we allow impls on the base type. // FIXME(pattern_types): Figure out the exact coherence rules we want here. diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 261be884025f1..07ad5db47b6d8 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -172,7 +172,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> for &impl_def_id in impls { let impl_header = tcx.impl_trait_header(impl_def_id); - let trait_ref = impl_header.trait_ref.instantiate_identity(); + let trait_ref = impl_header.trait_ref.instantiate_identity().skip_norm_wip(); let trait_def = tcx.trait_def(trait_ref.def_id); res = res diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index fe9639bf17d77..233f3798ce2b8 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -7,6 +7,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; @@ -22,7 +23,7 @@ pub(crate) fn orphan_check_impl( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip(); trait_ref.error_reported()?; match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) { @@ -301,13 +302,13 @@ fn orphan_check<'tcx>( let infcx = tcx.infer_ctxt().build(TypingMode::Coherence); let cause = traits::ObligationCause::dummy(); let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id()); - let trait_ref = trait_ref.instantiate(tcx, args); + let trait_ref = trait_ref.instantiate(tcx, args).skip_norm_wip(); let lazily_normalize_ty = |user_ty: Ty<'tcx>| { let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) }; let ocx = traits::ObligationCtxt::new(&infcx); - let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty); + let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), Unnormalized::new_wip(user_ty)); let ty = infcx.resolve_vars_if_possible(ty); let errors = ocx.try_evaluate_obligations(); if !errors.is_empty() { @@ -318,7 +319,7 @@ fn orphan_check<'tcx>( ocx.structurally_normalize_ty( &cause, ty::ParamEnv::empty(), - infcx.resolve_vars_if_possible(ty), + Unnormalized::new_wip(infcx.resolve_vars_if_possible(ty)), ) .unwrap_or(ty) } else { diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 86839e4033034..8114106a2a411 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -18,7 +18,7 @@ pub(super) fn check_item( ) -> Result<(), ErrorGuaranteed> { let unsafe_attr = tcx.generics_of(def_id).own_params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); - let trait_ref = trait_header.trait_ref.instantiate_identity(); + let trait_ref = trait_header.trait_ref.instantiate_identity().skip_norm_wip(); let is_copy = tcx.is_lang_item(trait_def.def_id, LangItem::Copy); let trait_def_safety = if is_copy { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 91f6c1a08f152..e407c0f3a91fb 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -34,7 +34,8 @@ use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ - self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, fold_regions, + self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, + fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -388,7 +389,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { let candidates = candidates .into_iter() .filter(|&InherentAssocCandidate { impl_, .. }| { - let impl_ty = self.tcx().type_of(impl_).instantiate_identity(); + let impl_ty = self.tcx().type_of(impl_).instantiate_identity().skip_norm_wip(); // See comment on doing this operation for `self_ty` let impl_ty = self.tcx.expand_free_alias_tys(impl_ty); @@ -1033,8 +1034,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn Ctor(data) => { assert_matches!(data.ctor(), Some(_)); let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id(); - let ty = tcx.type_of(adt_def_id).instantiate_identity(); - let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity()); + let ty = tcx.type_of(adt_def_id).instantiate_identity().skip_norm_wip(); + let inputs = data + .fields() + .iter() + .map(|f| tcx.type_of(f.def_id).instantiate_identity().skip_norm_wip()); // constructors for structs with `layout_scalar_valid_range` are unsafe to call let safety = match tcx.layout_scalar_valid_range(adt_def_id) { (Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe, @@ -1341,7 +1345,11 @@ pub fn suggest_impl_trait<'tcx>( let item_ty = ocx.normalize( &ObligationCause::dummy(), param_env, - Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args), + Unnormalized::new_wip(Ty::new_projection_from_args( + infcx.tcx, + assoc_item_def_id, + args, + )), ); // FIXME(compiler-errors): We may benefit from resolving regions here. if ocx.try_evaluate_obligations().is_empty() @@ -1375,7 +1383,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader let of_trait = impl_ .of_trait .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); - let selfty = tcx.type_of(def_id).instantiate_identity(); + let selfty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); let is_rustc_reservation = find_attr!(tcx, def_id, RustcReservationImpl(..)); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); @@ -1599,9 +1607,10 @@ fn const_param_default<'tcx>( let def_id = local_def_id.to_def_id(); let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id)); - let ct = icx - .lowerer() - .lower_const_arg(default_ct, tcx.type_of(def_id).instantiate(tcx, identity_args)); + let ct = icx.lowerer().lower_const_arg( + default_ct, + tcx.type_of(def_id).instantiate(tcx, identity_args).skip_norm_wip(), + ); ty::EarlyBinder::bind(ct) } @@ -1715,9 +1724,10 @@ fn const_of_item<'tcx>( }; let icx = ItemCtxt::new(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - let ct = icx - .lowerer() - .lower_const_arg(ct_arg, tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args)); + let ct = icx.lowerer().lower_const_arg( + ct_arg, + tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args).skip_norm_wip(), + ); if let Err(e) = icx.check_tainted_by_errors() && !ct.references_error() { diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index f1bb90fcbe897..16523462f65ba 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -3,7 +3,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::{find_attr, intravisit}; use rustc_middle::hir::nested_filter; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::sym; pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { @@ -20,7 +20,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { continue; } - let ty = tcx.type_of(id).instantiate_identity(); + let ty = tcx.type_of(id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(id); tcx.dcx().emit_err(crate::errors::TypeOf { span, ty }); } @@ -32,7 +32,12 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { let attrs = tcx.get_all_attrs(id); if find_attr!(attrs, RustcDumpPredicates) { - let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates; + let preds = tcx + .predicates_of(id) + .instantiate_identity(tcx) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip); let span = tcx.def_span(id); let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str()); @@ -47,7 +52,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { match tcx.def_kind(id) { DefKind::AssocTy => { - let bounds = tcx.item_bounds(id).instantiate_identity(); + let bounds = tcx.item_bounds(id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(id); let mut diag = tcx.dcx().struct_span_err(span, name); @@ -123,14 +128,14 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { let vtable_entries = match tcx.hir_item(id).kind { hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => { let trait_ref = tcx.impl_trait_ref(def_id).instantiate_identity(); - if trait_ref.has_non_region_param() { + if trait_ref.probe(|v| v.has_non_region_param()) { tcx.dcx().span_err( attr_span, "`rustc_dump_vtable` must be applied to non-generic impl", ); continue; } - if !tcx.is_dyn_compatible(trait_ref.def_id) { + if !tcx.is_dyn_compatible(trait_ref.probe(|v| v.def_id)) { tcx.dcx().span_err( attr_span, "`rustc_dump_vtable` must be applied to dyn-compatible trait", @@ -150,7 +155,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { } hir::ItemKind::TyAlias(..) => { let ty = tcx.type_of(def_id).instantiate_identity(); - if ty.has_non_region_param() { + if ty.probe(|v| v.has_non_region_param()) { tcx.dcx().span_err( attr_span, "`rustc_dump_vtable` must be applied to non-generic type", diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 98ac52e959297..4409f2c068eb8 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -558,7 +558,7 @@ impl<'tcx> TypeFolder> for AssocTyToOpaque<'tcx> { self.tcx.opt_rpitit_info(projection_ty_def_id) && fn_def_id == self.fn_def_id { - self.tcx.type_of(projection_ty_def_id).instantiate(self.tcx, args) + self.tcx.type_of(projection_ty_def_id).instantiate(self.tcx, args).skip_norm_wip() } else { ty.super_fold_with(self) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d70ee74a9b2aa..bd1faded7587a 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -92,8 +92,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // parent predicates would hold, and also so that the param-env // inherits these predicates as assumptions. let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - predicates - .extend(tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_args)); + predicates.extend( + tcx.explicit_predicates_of(fn_def_id) + .instantiate_own(tcx, identity_args) + .map(|(c, s)| (c.skip_norm_wip(), s)), + ); // We also install bidirectional outlives predicates for the RPITIT // to keep the duplicates lifetimes from opaque lowering in sync. @@ -118,12 +121,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let impl_def_id = tcx.parent(fn_def_id); - let impl_trait_ref_args = tcx.impl_trait_ref(impl_def_id).instantiate_identity().args; + let impl_trait_ref_args = + tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip().args; let impl_assoc_args = impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args); - let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_args); + let impl_predicates = trait_assoc_predicates + .instantiate_own(tcx, impl_assoc_args) + .map(|(c, s)| (c.skip_norm_wip(), s)); return ty::GenericPredicates { parent: Some(impl_def_id), @@ -161,8 +167,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen if let Some(of_trait) = impl_.of_trait && of_trait.defaultness.is_default() { - is_default_impl_trait = - Some(ty::Binder::dummy(tcx.impl_trait_ref(def_id).instantiate_identity())); + is_default_impl_trait = Some(ty::Binder::dummy( + tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip(), + )); } } ItemKind::Trait(_, _, _, _, _, _, self_bounds, ..) @@ -248,7 +255,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } hir::GenericParamKind::Const { .. } => { let param_def_id = param.def_id.to_def_id(); - let ct_ty = tcx.type_of(param_def_id).instantiate_identity(); + let ct_ty = tcx.type_of(param_def_id).instantiate_identity().skip_norm_wip(); let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id); predicates .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span)); @@ -345,9 +352,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // in trait checking. See `setup_constraining_predicates` // for details. if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node { - let self_ty = tcx.type_of(def_id).instantiate_identity(); - let trait_ref = - impl_.of_trait.is_some().then(|| tcx.impl_trait_ref(def_id).instantiate_identity()); + let self_ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); + let trait_ref = impl_ + .of_trait + .is_some() + .then(|| tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip()); cgp::setup_constraining_predicates( tcx, &mut predicates, @@ -465,18 +474,18 @@ fn const_evaluatable_predicates_of<'tcx>( if impl_.of_trait.is_some() { debug!("visit impl trait_ref"); let trait_ref = tcx.impl_trait_ref(def_id); - trait_ref.instantiate_identity().visit_with(&mut collector); + trait_ref.instantiate_identity().skip_norm_wip().visit_with(&mut collector); } debug!("visit self_ty"); let self_ty = tcx.type_of(def_id); - self_ty.instantiate_identity().visit_with(&mut collector); + self_ty.instantiate_identity().skip_norm_wip().visit_with(&mut collector); } if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) { debug!("visit fn sig"); let fn_sig = tcx.fn_sig(def_id); - let fn_sig = fn_sig.instantiate_identity(); + let fn_sig = fn_sig.instantiate_identity().skip_norm_wip(); debug!(?fn_sig); fn_sig.visit_with(&mut collector); } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index eeaf56adcbc2f..5c439824e7cd3 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -23,7 +23,7 @@ use rustc_macros::extension; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::{Ident, Span, sym}; @@ -1883,7 +1883,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { .map(|param| generic_param_def_as_bound_arg(param)), ); bound_vars.extend( - self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars(), + self.tcx + .fn_sig(assoc_fn.def_id) + .instantiate_identity() + .skip_norm_wip() + .bound_vars(), ); bound_vars } else { @@ -1967,21 +1971,24 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { break Some((bound_vars.into_iter().collect(), assoc_item)); } let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_ident)); - let obligations = predicates.iter_identity_copied().filter_map(|(pred, _)| { - let bound_predicate = pred.kind(); - match bound_predicate.skip_binder() { - ty::ClauseKind::Trait(data) => { - // The order here needs to match what we would get from - // `rustc_middle::ty::predicate::Clause::instantiate_supertrait` - let pred_bound_vars = bound_predicate.bound_vars(); - let mut all_bound_vars = bound_vars.clone(); - all_bound_vars.extend(pred_bound_vars.iter()); - let super_def_id = data.trait_ref.def_id; - Some((super_def_id, all_bound_vars)) + let obligations = predicates + .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) + .filter_map(|(pred, _)| { + let bound_predicate = pred.kind(); + match bound_predicate.skip_binder() { + ty::ClauseKind::Trait(data) => { + // The order here needs to match what we would get from + // `rustc_middle::ty::predicate::Clause::instantiate_supertrait` + let pred_bound_vars = bound_predicate.bound_vars(); + let mut all_bound_vars = bound_vars.clone(); + all_bound_vars.extend(pred_bound_vars.iter()); + let super_def_id = data.trait_ref.def_id; + Some((super_def_id, all_bound_vars)) + } + _ => None, } - _ => None, - } - }); + }); let obligations = obligations.filter(|o| visited.insert(o.0)); stack.extend(obligations); @@ -2197,7 +2204,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { .iter() .map(|param| generic_param_def_as_bound_arg(param)), ); - bound_vars.extend(self.tcx.fn_sig(item_def_id).instantiate_identity().bound_vars()); + bound_vars.extend( + self.tcx.fn_sig(item_def_id).instantiate_identity().skip_norm_wip().bound_vars(), + ); // SUBTLE: Stash the old bound vars onto the *item segment* before appending // the new bound vars. We do this because we need to know how many bound vars @@ -2453,7 +2462,9 @@ fn is_late_bound_map( arg_is_constrained: vec![false; generics.own_params.len()] .into_boxed_slice(), }; - walker.visit_ty(self.tcx.type_of(*alias_def).instantiate_identity()); + walker.visit_ty( + self.tcx.type_of(*alias_def).instantiate_identity().skip_norm_wip(), + ); match segments.last() { Some(hir::PathSegment { args: Some(args), .. }) => { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index e65efd6880b85..aeb9be39c3143 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -182,7 +182,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } }, - Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity(), + Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity().skip_norm_wip(), Node::ForeignItem(foreign_item) => match foreign_item.kind { ForeignItemKind::Fn(..) => { @@ -205,7 +205,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { VariantData::Unit(..) | VariantData::Struct { .. } => { - tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity() + tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity().skip_norm_wip() } VariantData::Tuple(_, _, ctor) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); @@ -356,7 +356,7 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. }) if c.hir_id == hir_id => { - tcx.type_of(field_def_id).instantiate_identity() + tcx.type_of(field_def_id).instantiate_identity().skip_norm_wip() } _ => Ty::new_error_with_message( @@ -418,7 +418,7 @@ fn infer_placeholder_type<'tcx>( // which `type const`s don't. let ty = if tcx.is_type_const(def_id.to_def_id()) { if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) { - tcx.type_of(trait_item_def_id).instantiate_identity() + tcx.type_of(trait_item_def_id).instantiate_identity().skip_norm_wip() } else { Ty::new_error_with_message( tcx, diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index e97830ccd23fa..c62e41b55edcd 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -281,9 +281,9 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) -> } (FnKind::AssocTraitImpl, FnKind::AssocTrait) - | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { - Some(tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity()) - } + | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some( + tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(), + ), // For trait impl's `sig_id` is always equal to the corresponding trait method. // For inherent methods delegation is not yet supported. @@ -339,7 +339,8 @@ fn create_generic_args<'tcx>( // them as parent args. We always generate a function whose generics match // child generics in trait. let parent = tcx.local_parent(delegation_id); - parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().args; + parent_args = + tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args; assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); @@ -347,7 +348,8 @@ fn create_generic_args<'tcx>( } (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { - let self_ty = tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity(); + let self_ty = + tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(); tcx.mk_args_from_iter( std::iter::once(ty::GenericArg::from(self_ty)) @@ -457,7 +459,10 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>( for pred in preds.predicates { let new_pred = pred.0.fold_with(&mut self.folder); - self.preds.push((EarlyBinder::bind(new_pred).instantiate(self.tcx, args), pred.1)); + self.preds.push(( + EarlyBinder::bind(new_pred).instantiate(self.tcx, args).skip_norm_wip(), + pred.1, + )); } self diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index c86573e2493ed..bf6b7e24f14e3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -543,7 +543,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => { let ty = projection_term.map_bound(|alias| { - tcx.type_of(alias.def_id).instantiate(tcx, alias.args) + tcx.type_of(alias.def_id).instantiate(tcx, alias.args).skip_norm_wip() }); let ty = check_assoc_const_binding_type( self, @@ -851,7 +851,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `rustc_middle::ty::predicate::Clause::instantiate_supertrait` // and it's no coincidence why. let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); - Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args)) + Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args).skip_norm_wip()) } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 6bcc2e40e5248..784deffce434c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -436,7 +436,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx) && header.polarity != ty::ImplPolarity::Negative }) - .map(|header| header.trait_ref.instantiate_identity().self_ty()) + .map(|header| header.trait_ref.instantiate_identity().skip_norm_wip().self_ty()) // We don't care about blanket impls. .filter(|self_ty| !self_ty.has_non_region_param()) .map(|self_ty| tcx.erase_and_anonymize_regions(self_ty).to_string()) @@ -511,7 +511,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } Some((hir::def::CtorKind::Fn, def_id)) => { // tuple - let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let inputs = fn_sig.inputs().skip_binder(); suggestion = vec![( ident.span.with_hi(expr.span.hi()), @@ -728,7 +728,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { "the candidate".into() }; - let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity(); + let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity().skip_norm_wip(); let note = format!("{title} is defined in an impl for the type `{impl_ty}`"); if let Some(span) = note_span { @@ -782,7 +782,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .take(limit) .map(|cand| { - format!("- `{}`", tcx.at(span).type_of(cand.impl_).instantiate_identity()) + format!( + "- `{}`", + tcx.at(span).type_of(cand.impl_).instantiate_identity().skip_norm_wip() + ) }) .collect::>() .join("\n"); @@ -1786,7 +1789,7 @@ fn generics_args_err_extend<'a>( ); } GenericsArgsErrExtend::SelfTyAlias { def_id, span } => { - let ty = tcx.at(span).type_of(def_id).instantiate_identity(); + let ty = tcx.at(span).type_of(def_id).instantiate_identity().skip_norm_wip(); let span_of_impl = tcx.span_of_impl(def_id); let ty::Adt(self_def, _) = *ty.kind() else { return }; let def_id = self_def.did(); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 596f538a9d3bb..a43084b4fbf1a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -75,7 +75,8 @@ fn generic_arg_mismatch_err( Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { let param_name = tcx.hir_ty_param_name(param_local_id); - let param_type = tcx.type_of(param.def_id).instantiate_identity(); + let param_type = + tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip(); if param_type.is_suggestable(tcx, false) { err.span_suggestion_verbose( tcx.def_span(src_def_id), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index c47bd227e3d94..b067307a93ec9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -39,7 +39,8 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::{ self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, Ty, TyCtxt, - TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, const_lit_matches_ty, fold_regions, + TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, const_lit_matches_ty, + fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; @@ -717,7 +718,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Ambig portions of `ConstArg` are handled in the match arm below .lower_const_arg( ct.as_unambig_ct(), - tcx.type_of(param.def_id).instantiate(tcx, preceding_args), + tcx.type_of(param.def_id) + .instantiate(tcx, preceding_args) + .skip_norm_wip(), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -762,6 +765,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.at(self.span) .type_of(param.def_id) .instantiate(tcx, preceding_args) + .skip_norm_wip() .into() } else if synthetic { Ty::new_param(tcx, param.index, param.name).into() @@ -776,13 +780,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = tcx .at(self.span) .type_of(param.def_id) - .instantiate(tcx, preceding_args); + .instantiate(tcx, preceding_args) + .skip_norm_wip(); if let Err(guar) = ty.error_reported() { return ty::Const::new_error(tcx, guar).into(); } if !infer_args && has_default { tcx.const_param_default(param.def_id) .instantiate(tcx, preceding_args) + .skip_norm_wip() .into() } else if infer_args { self.lowerer.ct_infer(Some(param), self.span).into() @@ -1151,7 +1157,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id }, args); Ty::new_alias(tcx, alias_ty) } else { - tcx.at(span).type_of(def_id).instantiate(tcx, args) + tcx.at(span).type_of(def_id).instantiate(tcx, args).skip_norm_wip() } } @@ -1181,6 +1187,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { || { let trait_refs = predicates .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))); traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident) }, @@ -1302,7 +1309,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME(mgca): code duplication with other places we lower // the rhs' of associated const bindings let ty = projection_term.map_bound(|alias| { - tcx.type_of(alias.def_id).instantiate(tcx, alias.args) + tcx.type_of(alias.def_id) + .instantiate(tcx, alias.args) + .skip_norm_wip() }); let ty = bounds::check_assoc_const_binding_type( self, @@ -1646,7 +1655,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.probe_single_bound_for_assoc_item( || { - let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity()); + let trait_ref = + ty::Binder::dummy(trait_ref.instantiate_identity().skip_norm_wip()); traits::supertraits(tcx, trait_ref) }, AssocItemQSelf::SelfTyAlias, @@ -1879,10 +1889,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && tcx.all_impls(*trait_def_id) .any(|impl_def_id| { let header = tcx.impl_trait_header(impl_def_id); - let trait_ref = header.trait_ref.instantiate( - tcx, - infcx.fresh_args_for_item(DUMMY_SP, impl_def_id), - ); + let trait_ref = header.trait_ref.instantiate(tcx, infcx.fresh_args_for_item(DUMMY_SP, impl_def_id)).skip_norm_wip(); let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased); // FIXME: Don't bother dealing with non-lifetime binders here... @@ -2241,7 +2248,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. - let ty = tcx.at(span).type_of(def_id).instantiate_identity(); + let ty = tcx.at(span).type_of(def_id).instantiate_identity().skip_norm_wip(); let _ = self.prohibit_generic_args( path.segments.iter(), GenericsArgsErrExtend::SelfTyAlias { def_id, span }, @@ -2550,7 +2557,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .iter() .zip(args) .map(|(field_def, arg)| { - self.lower_const_arg(arg, tcx.type_of(field_def.did).instantiate(tcx, adt_args)) + self.lower_const_arg( + arg, + tcx.type_of(field_def.did).instantiate(tcx, adt_args).skip_norm_wip(), + ) }) .collect::>(); @@ -2671,7 +2681,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_const_arg( expr.expr, - tcx.type_of(field_def.did).instantiate(tcx, adt_args), + tcx.type_of(field_def.did).instantiate(tcx, adt_args).skip_norm_wip(), ) } None => { @@ -2880,7 +2890,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // FIXME(generic_const_parameter_types): We should use the proper generic args // here. It's only used as a hint for literals so doesn't matter too much to use the right // generic arguments, just weaker type inference. - let ty = tcx.type_of(anon.def_id).instantiate_identity(); + let ty = tcx.type_of(anon.def_id).instantiate_identity().skip_norm_wip(); match self.try_lower_anon_const_lit(ty, expr) { Some(v) => v, @@ -2991,7 +3001,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn lower_delegation_ty(&self, infer: hir::InferDelegation<'tcx>) -> Ty<'tcx> { match infer { hir::InferDelegation::DefId(def_id) => { - self.tcx().type_of(def_id).instantiate_identity() + self.tcx().type_of(def_id).instantiate_identity().skip_norm_wip() } rustc_hir::InferDelegation::Sig(_, idx) => { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); @@ -3578,10 +3588,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref.def_id, )?; - let fn_sig = tcx.fn_sig(assoc.def_id).instantiate( - tcx, - trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), - ); + let fn_sig = tcx + .fn_sig(assoc.def_id) + .instantiate( + tcx, + trait_ref + .args + .extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), + ) + .skip_norm_wip(); let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig); Some(if let Some(arg_idx) = arg_idx { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 57ee790170384..82081fd40a274 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -16,7 +16,7 @@ use rustc_errors::Applicability; use rustc_errors::codes::*; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::{ErrorGuaranteed, kw}; use crate::constrained_generic_params as cgp; @@ -78,7 +78,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( impl_def_id: LocalDefId, of_trait: bool, ) -> Result<(), ErrorGuaranteed> { - let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); + let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip(); // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) @@ -86,7 +86,8 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate_identity()); + let impl_trait_ref = + of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip()); impl_trait_ref.error_reported()?; @@ -107,7 +108,11 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( match item.kind { ty::AssocKind::Type { .. } => { if item.defaultness(tcx).has_value() { - cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true) + cgp::parameters_for( + tcx, + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), + true, + ) } else { vec![] } @@ -187,7 +192,7 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); + let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip(); // Don't complain about unconstrained type params when self ty isn't known due to errors. // (#36836) @@ -195,8 +200,10 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained( let impl_generics = tcx.generics_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id); - let impl_trait_ref = - tcx.impl_opt_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); + let impl_trait_ref = tcx + .impl_opt_trait_ref(impl_def_id) + .map(ty::EarlyBinder::instantiate_identity) + .map(Unnormalized::skip_norm_wip); impl_trait_ref.error_reported()?; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 47bd2fd37dff5..1fb126fe3d69f 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -215,7 +215,7 @@ fn unconstrained_parent_impl_args<'tcx>( let impl_generic_predicates = tcx.predicates_of(impl_def_id); let mut unconstrained_parameters = FxHashSet::default(); let mut constrained_params = FxHashSet::default(); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip(); // Unfortunately the functions in `constrained_generic_parameters` don't do // what we want here. We want only a list of constrained parameters while @@ -326,7 +326,10 @@ fn check_predicates<'tcx>( ) -> Result<(), ErrorGuaranteed> { let impl1_predicates: Vec<_> = traits::elaborate( tcx, - tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_args).into_iter(), + tcx.predicates_of(impl1_def_id) + .instantiate(tcx, impl1_args) + .into_iter() + .map(|(c, s)| (c.skip_norm_wip(), s)), ) .collect(); @@ -340,7 +343,7 @@ fn check_predicates<'tcx>( tcx.predicates_of(impl2_node.def_id()) .instantiate(tcx, impl2_args) .into_iter() - .map(|(c, _s)| c.as_predicate()), + .map(|(c, _s)| c.skip_norm_wip().as_predicate()), ) .collect() }; @@ -373,7 +376,7 @@ fn check_predicates<'tcx>( .map(|(c, _span)| c.as_predicate()); // Include the well-formed predicates of the type parameters of the impl. - for arg in tcx.impl_trait_ref(impl1_def_id).instantiate_identity().args { + for arg in tcx.impl_trait_ref(impl1_def_id).instantiate_identity().skip_norm_wip().args { let Some(term) = arg.as_term() else { continue; }; diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index e6081a48574d8..23e6b2281b370 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -46,7 +46,8 @@ pub(super) fn infer_predicates( // For field of type &'a T (reference) or Adt // (struct/enum/union) there will be outlive // requirements for adt_def. - let field_ty = tcx.type_of(field_def.did).instantiate_identity(); + let field_ty = + tcx.type_of(field_def.did).instantiate_identity().skip_norm_wip(); let field_span = tcx.def_span(field_def.did); insert_required_predicates_to_be_wf( tcx, @@ -62,7 +63,7 @@ pub(super) fn infer_predicates( DefKind::TyAlias if tcx.type_alias_is_lazy(item_did) => { insert_required_predicates_to_be_wf( tcx, - tcx.type_of(item_did).instantiate_identity(), + tcx.type_of(item_did).instantiate_identity().skip_norm_wip(), tcx.def_span(item_did), &global_inferred_outlives, &mut item_required_predicates, @@ -306,7 +307,8 @@ fn check_explicit_predicates<'tcx>( continue; } - let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args); + let predicate = + explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args).skip_norm_wip(); debug!("predicate = {predicate:?}"); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); } @@ -349,7 +351,7 @@ fn check_inferred_predicates<'tcx>( // `predicate` is `U: 'b` in the example above. // So apply the instantiation to get `T: 'a`. let ty::OutlivesPredicate(arg, region) = - predicates.rebind(predicate).instantiate(tcx, args); + predicates.rebind(predicate).instantiate(tcx, args).skip_norm_wip(); insert_outlives_predicate(tcx, arg, region, span, required_predicates); } } diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index e9df40e1108a1..a45856937a8e0 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let inferred_start = self.terms_cx.inferred_starts[&def_id]; let current_item = &CurrentItem { inferred_start }; - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); // The type as returned by `type_of` is the underlying type and generally not a free alias. // Therefore we need to check the `DefKind` first. @@ -127,7 +127,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { for field in def.all_fields() { self.add_constraints_from_ty( current_item, - tcx.type_of(field.did).instantiate_identity(), + tcx.type_of(field.did).instantiate_identity().skip_norm_wip(), self.covariant, ); } @@ -136,7 +136,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::FnDef(..) => { self.add_constraints_from_sig( current_item, - tcx.fn_sig(def_id).instantiate_identity(), + tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(), self.covariant, ); } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index b9f875a3c629b..9c20ef1a73dcf 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -11,6 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::span_bug; use rustc_middle::ty::{ self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + Unnormalized, }; use tracing::{debug, instrument}; @@ -185,7 +186,11 @@ fn variance_of_opaque( let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id); - for (pred, _) in tcx.explicit_item_bounds(item_def_id).iter_instantiated_copied(tcx, id_args) { + for (pred, _) in tcx + .explicit_item_bounds(item_def_id) + .iter_instantiated_copied(tcx, id_args) + .map(Unnormalized::skip_norm_wip) + { debug!(?pred); // We only ignore opaque type args if the opaque type is the outermost type. diff --git a/compiler/rustc_hir_analysis/src/variance/solve.rs b/compiler/rustc_hir_analysis/src/variance/solve.rs index 4106c1a5b6355..eef26d783e7b7 100644 --- a/compiler/rustc_hir_analysis/src/variance/solve.rs +++ b/compiler/rustc_hir_analysis/src/variance/solve.rs @@ -122,7 +122,9 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { self.enforce_const_invariance(generics, variances); // Functions are permitted to have unused generic parameters: make those invariant. - if let ty::FnDef(..) = tcx.type_of(def_id).instantiate_identity().kind() { + if let ty::FnDef(..) = + tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() + { for variance in variances.iter_mut() { if *variance == ty::Bivariant { *variance = ty::Invariant; diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 3952d3889bb8f..67f19ac3b0f2c 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -12,7 +12,7 @@ use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::{Span, sym}; @@ -542,7 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (fn_sig, def_id) = match *callee_ty.kind() { ty::FnDef(def_id, args) => { self.enforce_context_effects(Some(call_expr.hir_id), call_expr.span, def_id, args); - let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args); + let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip(); // Unit testing: function items annotated with // `#[rustc_evaluate_where_clauses]` trigger special output @@ -551,6 +551,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, args); for (predicate, predicate_span) in predicates { + let predicate = predicate.skip_norm_wip(); let obligation = Obligation::new( self.tcx, ObligationCause::dummy_with_span(callee_expr.span), @@ -586,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BoundRegionConversionTime::FnCall, fn_sig, ); - let fn_sig = self.normalize(call_expr.span, fn_sig); + let fn_sig = self.normalize(call_expr.span, Unnormalized::new_wip(fn_sig)); self.check_argument_types( call_expr.span, @@ -949,6 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (idx, (cond, pred_span)) in q.instantiate(self.tcx, callee_args).into_iter().enumerate() { + let cond = cond.skip_norm_wip(); let cause = self.cause( span, if let Some(hir_id) = call_hir_id { diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f0021fc735194..93275f62dcc17 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -40,7 +40,9 @@ use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef, elaborate}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, Unnormalized, VariantDef, elaborate, +}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::{DUMMY_SP, Span, sym}; @@ -753,7 +755,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { match *self.expr_ty.kind() { ty::FnDef(..) => { // Attempt a coercion to a fn pointer type. - let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx)); + let f = fcx.normalize( + self.expr_span, + Unnormalized::new_wip(self.expr_ty.fn_sig(fcx.tcx)), + ); let res = fcx.coerce( self.expr, self.expr_ty, diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 612396858841f..f5c77d7af3aa3 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -60,7 +60,7 @@ pub(super) fn check_fn<'a, 'tcx>( let va_list_did = tcx.require_lang_item(LangItem::VaList, span); let region = fcx.next_region_var(RegionVariableOrigin::Misc(span)); - tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]) + tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]).skip_norm_wip() }); // Add formal parameters. @@ -181,14 +181,17 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_> let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span); // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` - let panic_info_ty = tcx.type_of(panic_info_did).instantiate( - tcx, - &[ty::GenericArg::from(ty::Region::new_bound( + let panic_info_ty = tcx + .type_of(panic_info_did) + .instantiate( tcx, - ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon }, - ))], - ); + &[ty::GenericArg::from(ty::Region::new_bound( + tcx, + ty::INNERMOST, + ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon }, + ))], + ) + .skip_norm_wip(); let panic_info_ref_ty = Ty::new_imm_ref( tcx, ty::Region::new_bound( diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 28bb9c5cd75b2..32730f221498c 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -14,7 +14,7 @@ use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::span_bug; use rustc_middle::ty::{ self, ClosureKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, + TypeVisitableExt, TypeVisitor, Unnormalized, }; use rustc_span::def_id::LocalDefId; use rustc_span::{DUMMY_SP, Span}; @@ -312,6 +312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .explicit_item_self_bounds(def_id) .iter_instantiated_copied(self.tcx, args) + .map(Unnormalized::skip_norm_wip) .map(|(c, s)| (c.as_predicate(), s)), ), ty::Dynamic(object_type, ..) => { @@ -374,11 +375,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let inferred_sig = self.normalize( span, - self.deduce_sig_from_projection( + Unnormalized::new_wip(self.deduce_sig_from_projection( Some(span), closure_kind, bound_predicate.rebind(proj_predicate), - ), + )), ); // Make sure that we didn't infer a signature that mentions itself. @@ -972,7 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result); // Normalize only after registering in `user_provided_sigs`. - self.normalize(self.tcx.def_span(expr_def_id), result) + self.normalize(self.tcx.def_span(expr_def_id), Unnormalized::new_wip(result)) } /// Invoked when we are translating the coroutine that results @@ -1028,6 +1029,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .explicit_item_self_bounds(def_id) .iter_instantiated_copied(self.tcx, args) + .map(Unnormalized::skip_norm_wip) .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, ty::Error(_) => return Some(ret_ty), _ => { @@ -1035,7 +1037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let output_ty = self.normalize(closure_span, output_ty); + let output_ty = self.normalize(closure_span, Unnormalized::new_wip(output_ty)); // async fn that have opaque types in their return type need to redo the conversion to inference variables // as they fetch the still opaque version from the signature. @@ -1142,7 +1144,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> ClosureSignatures<'tcx> { let liberated_sig = self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig); - let liberated_sig = self.normalize(self.tcx.def_span(expr_def_id), liberated_sig); + let liberated_sig = + self.normalize(self.tcx.def_span(expr_def_id), Unnormalized::new_wip(liberated_sig)); ClosureSignatures { bound_sig, liberated_sig } } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bfc677046e0f4..db8497f63023a 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{ PointerCoercion, }; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::{BytePos, DUMMY_SP, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor}; @@ -963,7 +963,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety))?; let InferOk { value: a_sig, mut obligations } = - self.at(&self.cause, self.param_env).normalize(a_sig); + self.at(&self.cause, self.param_env).normalize(Unnormalized::new_wip(a_sig)); let a = Ty::new_fn_ptr(self.tcx, a_sig); let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety)); @@ -1104,7 +1104,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.next_trait_solver() && let ty::Alias(..) = ty.kind() { - ocx.structurally_normalize_ty(&cause, self.param_env, ty) + ocx.structurally_normalize_ty(&cause, self.param_env, Unnormalized::new_wip(ty)) } else { Ok(ty) } @@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // The signature must match. - let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig)); + let (a_sig, b_sig) = self.normalize(new.span, Unnormalized::new_wip((a_sig, b_sig))); let sig = self .at(cause, self.param_env) .lub(a_sig, b_sig) @@ -1852,28 +1852,34 @@ impl<'tcx> CoerceMany<'tcx> { fcx.probe(|_| { let ocx = ObligationCtxt::new(fcx); ocx.register_obligations( - fcx.tcx.item_self_bounds(rpit_def_id).iter_identity().filter_map(|clause| { - let predicate = clause - .kind() - .map_bound(|clause| match clause { - ty::ClauseKind::Trait(trait_pred) => Some(ty::ClauseKind::Trait( - trait_pred.with_replaced_self_ty(fcx.tcx, ty), - )), - ty::ClauseKind::Projection(proj_pred) => { - Some(ty::ClauseKind::Projection( - proj_pred.with_replaced_self_ty(fcx.tcx, ty), - )) - } - _ => None, - }) - .transpose()?; - Some(Obligation::new( - fcx.tcx, - ObligationCause::dummy(), - fcx.param_env, - predicate, - )) - }), + fcx.tcx + .item_self_bounds(rpit_def_id) + .iter_identity() + .map(Unnormalized::skip_norm_wip) + .filter_map(|clause| { + let predicate = clause + .kind() + .map_bound(|clause| match clause { + ty::ClauseKind::Trait(trait_pred) => { + Some(ty::ClauseKind::Trait( + trait_pred.with_replaced_self_ty(fcx.tcx, ty), + )) + } + ty::ClauseKind::Projection(proj_pred) => { + Some(ty::ClauseKind::Projection( + proj_pred.with_replaced_self_ty(fcx.tcx, ty), + )) + } + _ => None, + }) + .transpose()?; + Some(Obligation::new( + fcx.tcx, + ObligationCause::dummy(), + fcx.param_env, + predicate, + )) + }), ); ocx.try_evaluate_obligations().is_empty() }) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e21cadcf3ffe6..849028bddb679 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -28,7 +28,7 @@ use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk, RegionVariableOrigin} use rustc_infer::traits::query::NoSolution; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::parse::feature_err; @@ -594,7 +594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_required_obligations_with_code(expr.span, def_id, args, |_, _| { code.clone() }); - return tcx.type_of(def_id).instantiate(tcx, args); + return tcx.type_of(def_id).instantiate(tcx, args).skip_norm_wip(); } } @@ -1743,7 +1743,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let count_span = count.span; let count = self.try_structurally_resolve_const( count_span, - self.normalize(count_span, self.lower_const_arg(count, tcx.types.usize)), + self.normalize( + count_span, + Unnormalized::new_wip(self.lower_const_arg(count, tcx.types.usize)), + ), ); if let Some(count) = count.try_to_target_usize(tcx) { @@ -2064,12 +2067,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(adt, args) if adt.is_struct() => variant .fields .iter() - .map(|f| self.normalize(span, f.ty(self.tcx, args))) + .map(|f| self.normalize(span, Unnormalized::new_wip(f.ty(self.tcx, args)))) .collect(), ty::Adt(adt, args) if adt.is_enum() => variant .fields .iter() - .map(|f| self.normalize(span, f.ty(self.tcx, args))) + .map(|f| self.normalize(span, Unnormalized::new_wip(f.ty(self.tcx, args)))) .collect(), _ => { self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span }); @@ -2095,7 +2098,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|f| { let fru_ty = self.normalize( expr.span, - self.field_ty(base_expr.span, f, fresh_args), + Unnormalized::new_wip(self.field_ty( + base_expr.span, + f, + fresh_args, + )), ); let ident = self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); @@ -2180,7 +2187,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(adt, args) if adt.is_struct() => variant .fields .iter() - .map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) + .map(|f| { + self.normalize( + expr.span, + Unnormalized::new_wip(f.ty(self.tcx, args)), + ) + }) .collect(), _ => { self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { @@ -2480,7 +2492,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let fn_sig = self .tcx .fn_sig(item.def_id) - .instantiate(self.tcx, self.fresh_args_for_item(span, item.def_id)); + .instantiate(self.tcx, self.fresh_args_for_item(span, item.def_id)) + .skip_norm_wip(); let ret_ty = self.tcx.instantiate_bound_regions_with_erased(fn_sig.output()); if !self.can_eq(self.param_env, ret_ty, adt_ty) { return None; @@ -2592,7 +2605,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); err.span_label(field.ident.span, "field does not exist"); - let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let inputs = fn_sig.inputs().skip_binder(); let fields = format!( "({})", @@ -2620,7 +2633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { err.span_label(variant_ident_span, format!("`{ty}` defined here")); err.span_label(field.ident.span, "field does not exist"); - let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let inputs = fn_sig.inputs().skip_binder(); let fields = format!( "({})", @@ -3215,7 +3228,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.span_label(field.span, "this is an associated function, not a method"); err.note("found the following associated function; to be used as method, it must have a `self` parameter"); - let impl_ty = self.tcx.type_of(impl_def_id).instantiate_identity(); + let impl_ty = + self.tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip(); err.span_note( self.tcx.def_span(item.def_id), format!("the candidate is defined in an impl for the type `{impl_ty}`"), @@ -3545,13 +3559,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ocx = ObligationCtxt::new_with_diagnostics(self); let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id); - let impl_trait_ref = - self.tcx.impl_trait_ref(impl_def_id).instantiate(self.tcx, impl_args); + let impl_trait_ref = self + .tcx + .impl_trait_ref(impl_def_id) + .instantiate(self.tcx, impl_args) + .skip_norm_wip(); let cause = self.misc(base_expr.span); // Match the impl self type against the base ty. If this fails, // we just skip this impl, since it's not particularly useful. - let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref); + let impl_trait_ref = + ocx.normalize(&cause, self.param_env, Unnormalized::new_wip(impl_trait_ref)); ocx.eq(&cause, self.param_env, base_ty, impl_trait_ref.self_ty())?; // Register the impl's predicates. One of these predicates @@ -3586,11 +3604,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let element_ty = ocx.normalize( &cause, self.param_env, - Ty::new_projection_from_args( + Unnormalized::new_wip(Ty::new_projection_from_args( self.tcx, index_trait_output_def_id, impl_trait_ref.args, - ), + )), ); let true_errors = ocx.try_evaluate_obligations(); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 5aadf37720d0c..00f3fb7fb5273 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -573,7 +573,8 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( match ex.kind { hir::ExprKind::MethodCall(..) => { if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) - && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() + && let method_ty = + self.fcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip() && let sig = method_ty.fn_sig(self.fcx.tcx) && sig.safety().is_unsafe() { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2cd0a05c723ad..9a54d651fe73a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity, - SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, - UserSelfTy, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, Unnormalized, + UserArgs, UserSelfTy, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -71,7 +71,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let impl_def_id = assoc_item.container_id(tcx); let generics = tcx.generics_of(def_id); let impl_args = &args[..generics.parent_count]; - let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args); + let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(); // Build new args: [Self, own_args...] let own_args = &args[generics.parent_count..]; tcx.mk_args_from_iter( @@ -423,7 +423,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn normalize(&self, span: Span, value: T) -> T + pub(crate) fn normalize(&self, span: Span, value: Unnormalized<'tcx, T>) -> T where T: TypeFoldable>, { @@ -474,7 +474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.next_trait_solver() { self.try_structurally_resolve_type(span, ty) } else { - self.normalize(span, ty) + self.normalize(span, Unnormalized::new_wip(ty)) } }, || {}, @@ -647,7 +647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: &'tcx ty::FieldDef, args: GenericArgsRef<'tcx>, ) -> Ty<'tcx> { - self.normalize(span, field.ty(self.tcx, args)) + self.normalize(span, Unnormalized::new_wip(field.ty(self.tcx, args))) } /// Drain all obligations that are stalled on coroutines defined in this body. @@ -1064,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Res::Local(hid) = res { let ty = self.local_ty(span, hid); - let ty = self.normalize(span, ty); + let ty = self.normalize(span, Unnormalized::new_wip(ty)); return (ty, res); } @@ -1131,7 +1131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = LoweredTy::from_raw( self, span, - tcx.at(span).type_of(impl_def_id).instantiate_identity(), + tcx.at(span).type_of(impl_def_id).instantiate_identity().skip_norm_wip(), ); // Firstly, check that this SelfCtor even comes from the item we're currently @@ -1289,7 +1289,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx .tcx .type_of(param.def_id) - .instantiate(self.fcx.tcx, preceding_args), + .instantiate(self.fcx.tcx, preceding_args) + .skip_norm_wip(), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -1309,7 +1310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !infer_args && let Some(default) = param.default_value(tcx) { // If we have a default, then it doesn't matter that we're not inferring // the type/const arguments: We provide the default where any is missing. - return default.instantiate(tcx, preceding_args); + return default.instantiate(tcx, preceding_args).skip_norm_wip(); } // If no type/const arguments were provided, we have to infer them. // This case also occurs as a result of some malformed input, e.g., @@ -1347,7 +1348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_user_type_annotation_from_args(hir_id, def_id, args_for_user_type, user_self_ty); // Normalize only after registering type annotations. - let args = self.normalize(span, args_raw); + let args = self.normalize(span, Unnormalized::new_wip(args_raw)); self.add_required_obligations_for_hir(span, def_id, args, hir_id); @@ -1365,7 +1366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // with the instantiated impl type. // This also occurs for an enum variant on a type alias. let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); - let self_ty = self.normalize(span, self_ty); + let self_ty = self.normalize(span, Unnormalized::new_wip(self_ty)); match self.at(&self.misc(span), self.param_env).eq( DefineOpaqueTypes::Yes, impl_ty, @@ -1444,9 +1445,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We need to use a separate variable here as otherwise the temporary for // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting // in a reentrant borrow, causing an ICE. - let result = self - .at(&self.misc(sp), self.param_env) - .structurally_normalize_ty(ty, &mut **self.fulfillment_cx.borrow_mut()); + let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_ty( + Unnormalized::new_wip(ty), + &mut **self.fulfillment_cx.borrow_mut(), + ); match result { Ok(normalized_ty) => normalized_ty, Err(errors) => { @@ -1473,9 +1475,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We need to use a separate variable here as otherwise the temporary for // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting // in a reentrant borrow, causing an ICE. - let result = self - .at(&self.misc(sp), self.param_env) - .structurally_normalize_const(ct, &mut **self.fulfillment_cx.borrow_mut()); + let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_const( + Unnormalized::new_wip(ct), + &mut **self.fulfillment_cx.borrow_mut(), + ); match result { Ok(normalized_ct) => normalized_ct, Err(errors) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index b45e0d984a250..8f529f4974d9c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .nth(idx) => { - pred + pred.skip_norm_wip() } ClauseFlavor::Const if let Some((pred, _)) = self @@ -67,7 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .into_iter() .nth(idx) => { - pred.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe) + pred.skip_norm_wip().to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe) } _ => return false, }; @@ -524,7 +524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { return Some(( expr_field.expr, - self.tcx.type_of(field.did).instantiate_identity(), + self.tcx.type_of(field.did).instantiate_identity().skip_norm_wip(), )); } } @@ -552,7 +552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { receiver: Option<&'tcx hir::Expr<'tcx>>, args: &'tcx [hir::Expr<'tcx>], ) -> bool { - let ty = self.tcx.type_of(def_id).instantiate_identity(); + let ty = self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if !ty.is_fn() { return false; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb31bcbf70f1b..ad162cadd7d79 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -18,7 +18,7 @@ use rustc_index::IndexVec; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TypeTrace}; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::Session; use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; @@ -95,8 +95,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // as otherwise we can wind up conservatively proving `Copy` which may // infer the repeat expr count to something that never required `Copy` in // the first place. - let count = self - .structurally_resolve_const(element.span, self.normalize(element.span, count)); + let count = self.structurally_resolve_const( + element.span, + self.normalize(element.span, Unnormalized::new_wip(count)), + ); // Avoid run on "`NotCopy: Copy` is not implemented" errors when the // repeat expr count is erroneous/unknown. The user might wind up @@ -1390,7 +1392,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // fn-like predicates with different args, but callable types really never // do that, so it's OK. for (predicate, span) in instantiated { - if let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder() + if let ty::ClauseKind::Trait(pred) = + predicate.skip_norm_wip().kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty && self.tcx.is_fn_trait(pred.def_id()) { @@ -3014,7 +3017,8 @@ impl<'a, 'b, 'tcx> ArgsCtxt<'a, 'b, 'tcx> { .fn_ctxt .tcx .fn_sig(assoc.def_id) - .instantiate(self.call_ctxt.fn_ctxt.tcx, args); + .instantiate(self.call_ctxt.fn_ctxt.tcx, args) + .skip_norm_wip(); self.call_ctxt.fn_ctxt.instantiate_binder_with_fresh_vars( call_name.span, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 419fc8e82be6b..8a3ec8700e50e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_hir_analysis::hir_ty_lowering::{ }; use rustc_infer::infer::{self, RegionVariableOrigin}; use rustc_infer::traits::{DynCompatibilityViolation, Obligation}; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_session::Session; use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span}; use rustc_trait_selection::error_reporting::TypeErrCtxt; @@ -197,8 +197,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.probe(|_| { let ocx = ObligationCtxt::new(self); - let normalized_fn_sig = - ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig); + let normalized_fn_sig = ocx.normalize( + &ObligationCause::dummy(), + self.param_env, + Unnormalized::new_wip(fn_sig), + ); if ocx.evaluate_obligations_error_on_ambiguity().is_empty() { let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig); if !normalized_fn_sig.has_infer() { @@ -279,7 +282,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { self.trait_ascriptions.borrow_mut().entry(hir_id.local_id).or_default().push(clause); - let clause = self.normalize(span, clause); + let clause = self.normalize(span, Unnormalized::new_wip(clause)); self.register_predicate(Obligation::new( self.tcx, self.misc(span), @@ -326,7 +329,11 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { let mut filter_iat_candidate = |self_ty, impl_| { let ocx = ObligationCtxt::new_with_diagnostics(self); - let self_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, self_ty); + let self_ty = ocx.normalize( + &ObligationCause::dummy(), + self.param_env, + Unnormalized::new_wip(self_ty), + ); let impl_args = infcx.fresh_args_for_item(span, impl_); let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args); @@ -410,7 +417,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { if self.next_trait_solver() { self.try_structurally_resolve_type(span, ty).ty_adt_def() } else { - self.normalize(span, ty).ty_adt_def() + self.normalize(span, Unnormalized::new_wip(ty)).ty_adt_def() } } _ => None, @@ -433,7 +440,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { self.add_required_obligations_for_hir(span, *def_id, args, hir_id); } - self.normalize(span, ty) + self.normalize(span, Unnormalized::new_wip(ty)) } else { ty }; @@ -488,7 +495,7 @@ impl<'tcx> LoweredTy<'tcx> { let normalized = if fcx.next_trait_solver() { fcx.try_structurally_resolve_type(span, raw) } else { - fcx.normalize(span, raw) + fcx.normalize(span, Unnormalized::new_wip(raw)) }; LoweredTy { raw, normalized } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index a2f4c57bd442c..82c7f5e59c47e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -19,7 +19,7 @@ use rustc_middle::middle::stability::EvalResult; use rustc_middle::span_bug; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast, + self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, suggest_constraining_type_params, }; use rustc_session::errors::ExprParenthesesNeeded; @@ -965,7 +965,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let bound_vars = self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id)); let ty = Binder::bind_with_vars(ty, bound_vars); - let ty = self.normalize(hir_ty.span, ty); + let ty = self.normalize(hir_ty.span, Unnormalized::new_wip(ty)); let ty = self.tcx.instantiate_bound_regions_with_erased(ty); if self.may_coerce(expected, ty) { err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { @@ -1231,7 +1231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Asyncness::No => ty, }; - let ty = self.normalize(expr.span, ty); + let ty = self.normalize(expr.span, Unnormalized::new_wip(ty)); self.may_coerce(found, ty) } hir::FnRetTy::DefaultReturn(_) if in_closure => { @@ -1839,7 +1839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Same item return false; } - let item_ty = self.tcx.type_of(item.def_id).instantiate_identity(); + let item_ty = self.tcx.type_of(item.def_id).instantiate_identity().skip_norm_wip(); // FIXME(compiler-errors): This check is *so* rudimentary if item_ty.has_param() { return false; diff --git a/compiler/rustc_hir_typeck/src/inline_asm.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs index f2b746ac96b10..23f07b1734fda 100644 --- a/compiler/rustc_hir_typeck/src/inline_asm.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -5,7 +5,9 @@ use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; -use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; +use rustc_middle::ty::{ + self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy, Unnormalized, +}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; @@ -119,7 +121,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } else { self.fcx.tcx.normalize_erasing_regions( self.fcx.typing_env(self.fcx.param_env), - len, + Unnormalized::new_wip(len), ) }; let Some(len) = len.try_to_target_usize(self.tcx()) else { diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 7567f8ba34883..2910ce218c3c2 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -7,7 +7,7 @@ use rustc_hir as hir; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_span::def_id::LocalDefId; use tracing::trace; @@ -78,7 +78,7 @@ fn check_transmute<'tcx>( ) { let span = || tcx.hir_span(hir_id); let normalize = |ty| { - if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) { + if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) { ty } else { Ty::new_error_with_message( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index fe8a9a9fb4f73..15729bc311e57 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -50,7 +50,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::config; use rustc_span::Span; @@ -144,7 +144,7 @@ fn typeck_with_inspect<'tcx>( // a suggestion later on. fcx.lowerer().lower_fn_ty(id, header.safety(), header.abi, decl, None, None) } else { - tcx.fn_sig(def_id).instantiate_identity() + tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip() }; check_abi(tcx, id, span, fn_sig.abi()); @@ -168,7 +168,7 @@ fn typeck_with_inspect<'tcx>( .inputs_and_output .iter() .enumerate() - .map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)), + .map(|(idx, ty)| fcx.normalize(arg_span(idx), Unnormalized::new_wip(ty))), ); if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) { @@ -188,12 +188,12 @@ fn typeck_with_inspect<'tcx>( // a suggestion later on. fcx.lowerer().lower_ty(ty) } else { - tcx.type_of(def_id).instantiate_identity() + tcx.type_of(def_id).instantiate_identity().skip_norm_wip() }; loops::check(tcx, def_id, body); - let expected_type = fcx.normalize(body.value.span, expected_type); + let expected_type = fcx.normalize(body.value.span, Unnormalized::new_wip(expected_type)); let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code); @@ -244,7 +244,7 @@ fn typeck_with_inspect<'tcx>( assert!(fcx.deferred_call_resolutions.borrow().is_empty()); for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) { - let ty = fcx.normalize(span, ty); + let ty = fcx.normalize(span, Unnormalized::new_wip(ty)); fcx.require_type_is_sized(ty, span, code); } @@ -408,14 +408,15 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti && let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container { let impl_def_id = item.container_id(tcx); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip(); let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( tcx, impl_def_id, impl_trait_ref.args, ); tcx.check_args_compatible(trait_item_def_id, args) - .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args)) + .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args).skip_norm_wip()) } else { Some(fcx.next_ty_var(span)) } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 3423f6b42bb26..0c83c1948d6f2 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::{ self, AssocContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, - TypeFoldable, TypeVisitableExt, UserArgs, + TypeFoldable, TypeVisitableExt, Unnormalized, UserArgs, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Span}; @@ -137,14 +137,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // traits, no trait system method can be called before this point because they // could alter our Self-type, except for normalizing the receiver from the // signature (which is also done during probing). - let method_sig_rcvr = self.normalize(self.span, method_sig.inputs()[0]); + let method_sig_rcvr = + self.normalize(self.span, Unnormalized::new_wip(method_sig.inputs()[0])); debug!( "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}", self_ty, method_sig_rcvr, method_sig, method_predicates ); self.unify_receivers(self_ty, method_sig_rcvr, pick); - let method_sig = self.normalize(self.span, method_sig); + let method_sig = self.normalize(self.span, Unnormalized::new_wip(method_sig)); // Make sure nobody calls `drop()` explicitly. self.check_for_illegal_method_calls(pick); @@ -460,7 +461,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.cfcx .tcx .type_of(param.def_id) - .instantiate(self.cfcx.tcx, preceding_args), + .instantiate(self.cfcx.tcx, preceding_args) + .skip_norm_wip(), ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -532,7 +534,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { } } - self.normalize(self.span, args) + self.normalize(self.span, Unnormalized::new_wip(args)) } fn unify_receivers( @@ -591,7 +593,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { debug!("method_predicates after instantiation = {:?}", method_predicates); - let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args); + let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args).skip_norm_wip(); debug!("type scheme instantiated, sig={:?}", sig); let sig = self.instantiate_binder_with_fresh_vars(sig); @@ -657,22 +659,25 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ) -> Option { let sized_def_id = self.tcx.lang_items().sized_trait()?; - traits::elaborate(self.tcx, predicates.predicates.iter().copied()) - // We don't care about regions here. - .filter_map(|pred| match pred.kind().skip_binder() { - ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => { - let span = predicates - .iter() - .find_map(|(p, span)| if p == pred { Some(span) } else { None }) - .unwrap_or(DUMMY_SP); - Some((trait_pred, span)) - } - _ => None, - }) - .find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() { - ty::Dynamic(..) => Some(span), - _ => None, - }) + traits::elaborate( + self.tcx, + predicates.predicates.iter().copied().map(Unnormalized::skip_norm_wip), + ) + // We don't care about regions here. + .filter_map(|pred| match pred.kind().skip_binder() { + ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => { + let span = predicates + .iter() + .find_map(|(p, span)| if p.skip_norm_wip() == pred { Some(span) } else { None }) + .unwrap_or(DUMMY_SP); + Some((trait_pred, span)) + } + _ => None, + }) + .find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() { + ty::Dynamic(..) => Some(span), + _ => None, + }) } fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index eef7f9ba495ac..97bd03aa35d78 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -15,7 +15,7 @@ use rustc_infer::infer::{BoundRegionConversionTime, InferOk}; use rustc_infer::traits::PredicateObligations; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ - self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt, + self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt, Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; @@ -421,7 +421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // N.B., instantiate late-bound regions before normalizing the // function signature so that normalization does not need to deal // with bound regions. - let fn_sig = tcx.fn_sig(def_id).instantiate(self.tcx, args); + let fn_sig = tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip(); let fn_sig = self.instantiate_binder_with_fresh_vars( obligation.cause.span, BoundRegionConversionTime::FnCall, @@ -429,7 +429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let InferOk { value: fn_sig, obligations: o } = - self.at(&obligation.cause, self.param_env).normalize(fn_sig); + self.at(&obligation.cause, self.param_env).normalize(Unnormalized::new_wip(fn_sig)); obligations.extend(o); // Register obligations for the parameters. This will include the diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 6cfa6e8d75175..e75a2068c0a34 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::elaborate::supertrait_def_ids; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}; use rustc_middle::ty::{ self, AssocContainer, AssocItem, GenericArgs, GenericArgsRef, GenericParamDefKind, ParamEnvAnd, - Ty, TyCtxt, TypeVisitableExt, Upcast, + Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -1073,7 +1073,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match method.kind { ty::AssocKind::Fn { .. } => self.probe(|_| { let args = self.fresh_args_for_item(self.span, method.def_id); - let fty = self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args); + let fty = + self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args).skip_norm_wip(); let fty = self.instantiate_binder_with_fresh_vars( self.span, BoundRegionConversionTime::FnCall, @@ -1971,10 +1972,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match probe.kind { InherentImplCandidate { impl_def_id, .. } => { let impl_args = self.fresh_args_for_item(self.span, impl_def_id); - let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args); + let impl_ty = self + .tcx + .type_of(impl_def_id) + .instantiate(self.tcx, impl_args) + .skip_norm_wip(); (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, impl_ty, impl_args); - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + xform_self_ty = + ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty)); match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) { Ok(()) => {} @@ -1984,7 +1990,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } // FIXME: Weirdly, we normalize the ret ty in this candidate, but no other candidates. - xform_ret_ty = ocx.normalize(cause, self.param_env, xform_ret_ty); + xform_ret_ty = + ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_ret_ty)); // Check whether the impl imposes obligations we have to worry about. let impl_def_id = probe.item.container_id(self.tcx); let impl_bounds = @@ -2033,10 +2040,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { BoundRegionConversionTime::FnCall, poly_trait_ref, ); - let trait_ref = ocx.normalize(cause, self.param_env, trait_ref); + let trait_ref = + ocx.normalize(cause, self.param_env, Unnormalized::new_wip(trait_ref)); (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + xform_self_ty = + ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty)); match self_ty.kind() { // HACK: opaque types will match anything for which their bounds hold. // Thus we need to prevent them from trying to match the `&_` autoref @@ -2106,7 +2115,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match ocx.structurally_normalize_ty( cause, self.param_env, - trait_ref.self_ty(), + Unnormalized::new_wip(trait_ref.self_ty()), ) { Ok(ty) => { if !matches!(ty.kind(), ty::Param(_)) { @@ -2121,7 +2130,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + xform_self_ty = + ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty)); match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) { Ok(()) => {} @@ -2184,7 +2194,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // but `self.return_type` is only set on the diagnostic-path, so we // should be okay doing it here. if !matches!(probe.kind, InherentImplCandidate { .. }) { - xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty); + xform_ret_ty = + ocx.normalize(&cause, self.param_env, Unnormalized::new_wip(xform_ret_ty)); } debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty); @@ -2557,7 +2568,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { assert_eq!(args.len(), generics.parent_count); let xform_fn_sig = if generics.is_own_empty() { - fn_sig.instantiate(self.tcx, args) + fn_sig.instantiate(self.tcx, args).skip_norm_wip() } else { let args = GenericArgs::for_item(self.tcx, method, |param, _| { let i = param.index as usize; @@ -2575,7 +2586,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } }); - fn_sig.instantiate(self.tcx, args) + fn_sig.instantiate(self.tcx, args).skip_norm_wip() }; self.tcx.instantiate_bound_regions_with_erased(xform_fn_sig) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index fa90c0c6269c4..1219b90420816 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -478,7 +478,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let has_deref = autoderef.step_count() > 0; if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { - ty = self.tcx.at(span).type_of(def.did()).instantiate_identity(); + ty = + self.tcx.at(span).type_of(def.did()).instantiate_identity().skip_norm_wip(); } } } @@ -1406,7 +1407,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // different from the received one // So we avoid suggestion method with Box // for instance - self.tcx.at(span).type_of(*def_id).instantiate_identity() + self.tcx + .at(span) + .type_of(*def_id) + .instantiate_identity() + .skip_norm_wip() != rcvr_ty } (Mode::Path, false, _) => true, @@ -1425,7 +1430,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![ StringPart::normal(format!("the {item_kind} was found for `")), StringPart::highlighted( - self.tcx.at(span).type_of(*only).instantiate_identity().to_string(), + self.tcx + .at(span) + .type_of(*only) + .instantiate_identity() + .skip_norm_wip() + .to_string(), ), StringPart::normal(format!("`")), ] @@ -1439,7 +1449,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|impl_item| { format!( "- `{}`", - self.tcx.at(span).type_of(*impl_item).instantiate_identity() + self.tcx + .at(span) + .type_of(*impl_item) + .instantiate_identity() + .skip_norm_wip() ) }) .collect::>() @@ -1534,7 +1548,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggestion = vec![(replacement_span, var_name.to_string())]; } (Some((hir::def::CtorKind::Fn, def_id)), hir::ExprKind::Call(rcvr, args)) => { - let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let inputs = fn_sig.inputs().skip_binder(); // FIXME: reuse the logic for "change args" suggestion to account for types // involved and detect things like substitution. @@ -1580,7 +1594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } (Some((hir::def::CtorKind::Fn, def_id)), _) => { - let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let inputs = fn_sig.inputs().skip_binder(); suggestion = vec![( replacement_span, @@ -2204,7 +2218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not methods because they don’t have an instance of the struct to work with. if def_kind == DefKind::AssocFn { let ty_args = self.infcx.fresh_args_for_item(span, similar_candidate.def_id); - let fn_sig = tcx.fn_sig(similar_candidate.def_id).instantiate(tcx, ty_args); + let fn_sig = + tcx.fn_sig(similar_candidate.def_id).instantiate(tcx, ty_args).skip_norm_wip(); let fn_sig = self.instantiate_binder_with_fresh_vars( span, BoundRegionConversionTime::FnCall, @@ -2287,8 +2302,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inherent_method.container_id(self.tcx), adt_args, ); - let fn_sig = - self.tcx.fn_sig(inherent_method.def_id).instantiate(self.tcx, args); + let fn_sig = self + .tcx + .fn_sig(inherent_method.def_id) + .instantiate(self.tcx, args) + .skip_norm_wip(); let fn_sig = self.instantiate_binder_with_fresh_vars( item_name.span, BoundRegionConversionTime::FnCall, @@ -2363,7 +2381,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None }; - let impl_ty = self.tcx.at(span).type_of(impl_did).instantiate_identity(); + let impl_ty = + self.tcx.at(span).type_of(impl_did).instantiate_identity().skip_norm_wip(); let insertion = match self.tcx.impl_opt_trait_ref(impl_did) { None => String::new(), @@ -2411,6 +2430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, self.fresh_args_for_item(sugg_span, impl_did), ) + .skip_norm_wip() .with_replaced_self_ty(self.tcx, rcvr_ty), idx, sugg_span, @@ -2510,6 +2530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .fn_sig(item.def_id) .instantiate(self.tcx, self.fresh_args_for_item(DUMMY_SP, item.def_id)) + .skip_norm_wip() .output(); let ret_ty = self.tcx.instantiate_bound_regions_with_erased(ret_ty); let ty::Adt(def, args) = ret_ty.kind() else { @@ -2591,7 +2612,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. // (#61411) - let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity(); + let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity().skip_norm_wip(); let target_ty = self .autoderef(sugg_span, rcvr_ty) .silence_errors() @@ -2628,9 +2649,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(_) = source { let first_arg = static_candidates.get(0).and_then(|candidate_source| { let (assoc_did, self_ty) = match candidate_source { - CandidateSource::Impl(impl_did) => { - (*impl_did, self.tcx.type_of(*impl_did).instantiate_identity()) - } + CandidateSource::Impl(impl_did) => ( + *impl_did, + self.tcx.type_of(*impl_did).instantiate_identity().skip_norm_wip(), + ), CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty), }; @@ -2641,7 +2663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // for CandidateSource::Impl, `Self` will be instantiated to a concrete type // but for CandidateSource::Trait, `Self` is still `Self` - let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity(); + let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity().skip_norm_wip(); sig.inputs().skip_binder().get(0).and_then(|first| { // if the type of first arg is the same as the current impl type, we should take the first arg into assoc function let first_ty = first.peel_refs(); @@ -2826,8 +2848,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else { continue; }; - let range_ty = - self.tcx.type_of(range_def_id).instantiate(self.tcx, &[actual.into()]); + let range_ty = self + .tcx + .type_of(range_def_id) + .instantiate(self.tcx, &[actual.into()]) + .skip_norm_wip(); let pick = self.lookup_probe_for_diagnostic( item_name, @@ -3492,6 +3517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .type_of(impl_def_id) .instantiate_identity() + .skip_norm_wip() .ty_adt_def() .is_some_and(|def| def.did() == adt.did()) }) { @@ -3623,7 +3649,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // just changing the path. && pick.item.is_method() && let Some(self_ty) = - self.tcx.fn_sig(pick.item.def_id).instantiate_identity().inputs().skip_binder().get(0) + self.tcx.fn_sig(pick.item.def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder().get(0) && self_ty.is_ref() { let suggested_path = match deref_ty.kind() { @@ -4585,7 +4611,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|imp_did| self.tcx.impl_trait_header(imp_did)) .filter(|header| header.polarity != ty::ImplPolarity::Positive) .any(|header| { - let imp = header.trait_ref.instantiate_identity(); + let imp = header.trait_ref.instantiate_identity().skip_norm_wip(); let imp_simp = simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid); imp_simp.is_some_and(|s| s == simp_rcvr_ty) diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index b73bfabe92e60..b7936ea47944c 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -3,7 +3,7 @@ use rustc_infer::traits::ObligationCause; use rustc_middle::bug; use rustc_middle::ty::{ self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType, - TypeVisitableExt, + TypeVisitableExt, Unnormalized, }; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::opaque_types::{ @@ -139,7 +139,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { continue; } - let expected = ty.ty.instantiate(tcx, opaque_type_key.args); + let expected = ty.ty.instantiate(tcx, opaque_type_key.args).skip_norm_wip(); self.demand_eqtype(hidden_type.span, expected, hidden_type.ty); } @@ -236,7 +236,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let cause = ObligationCause::misc(hidden_type.span, self.body_id); let at = self.at(&cause, self.param_env); - let hidden_type = match solve::deeply_normalize(at, hidden_type) { + let hidden_type = match solve::deeply_normalize(at, Unnormalized::new_wip(hidden_type)) { Ok(hidden_type) => hidden_type, Err(errors) => { let guar = self.err_ctxt().report_fulfillment_errors(errors); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 26f7d1ccffc93..7db5a1c9bbf36 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -19,7 +19,7 @@ use rustc_hir::{ use rustc_hir_analysis::autoderef::report_autoderef_recursion_limit_error; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::traits::PatternOriginExpr; -use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::parse::feature_err; @@ -2704,7 +2704,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.require_lang_item(hir::LangItem::DerefTarget, span), [source_ty], ); - let target_ty = self.normalize(span, target_ty); + let target_ty = self.normalize(span, Unnormalized::new_wip(target_ty)); self.try_structurally_resolve_type(span, target_ty) } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index df02974d2fb2d..41b984c81bead 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -44,7 +44,7 @@ use rustc_middle::mir::FakeReadCause; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::{ self, BorrowKind, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, - UpvarArgs, UpvarCapture, + Unnormalized, UpvarArgs, UpvarCapture, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -1188,7 +1188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let at = self.at(&cause, self.param_env); match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( at, - place.clone(), + Unnormalized::new_wip(place.clone()), vec![], ) { Ok((normalized, goals)) => { @@ -1214,7 +1214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // For the old solver we can rely on `normalize` to eagerly normalize aliases. - self.normalize(span, place) + self.normalize(span, Unnormalized::new_wip(place)) } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0cf1998ae28a2..e0d9970a5a16d 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::{ self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - fold_regions, + Unnormalized, fold_regions, }; use rustc_span::Span; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; @@ -623,6 +623,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { hidden_ty .ty .instantiate_identity() + .skip_norm_wip() .visit_with(&mut HasRecursiveOpaque { def_id, seen: Default::default(), @@ -947,7 +948,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(value).as_usize()]; match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( - at, value, universes, + at, + Unnormalized::new_wip(value), + universes, ) { Ok((value, goals)) => { self.nested_goals.extend(goals); @@ -1035,7 +1038,9 @@ impl<'tcx> TypeFolder> for EagerlyNormalizeConsts<'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - self.tcx.try_normalize_erasing_regions(self.typing_env, ct).unwrap_or(ct) + self.tcx + .try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(ct)) + .unwrap_or(ct) } } @@ -1060,7 +1065,7 @@ impl<'tcx> TypeVisitor> for HasRecursiveOpaque<'_, 'tcx> { if self.seen.insert(def_id) && let Some(hidden_ty) = self.opaques.get(&def_id) { - hidden_ty.ty.instantiate(self.tcx, args).visit_with(self)?; + hidden_ty.ty.instantiate(self.tcx, args).skip_norm_wip().visit_with(self)?; } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 0c447f7c69973..ad6dd5c3cad52 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -6,7 +6,7 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable, - TypeVisitableExt, + TypeVisitableExt, Unnormalized, }; use rustc_span::Span; use tracing::{debug, instrument}; @@ -264,7 +264,8 @@ impl<'tcx> InferCtxt<'tcx> { let actual = prev.unwrap_or_else(|| { let actual = tcx .type_of_opaque_hir_typeck(opaque_type_key.def_id) - .instantiate(self.tcx, opaque_type_key.args); + .instantiate(self.tcx, opaque_type_key.args) + .skip_norm_wip(); let actual = ty::fold_regions(tcx, actual, |re, _dbi| match re.kind() { ty::ReErased => self.next_region_var(RegionVariableOrigin::Misc(span)), _ => re, @@ -352,7 +353,9 @@ impl<'tcx> InferCtxt<'tcx> { }; let item_bounds = tcx.explicit_item_bounds(def_id); - for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { + for (predicate, _) in + item_bounds.iter_instantiated_copied(tcx, args).map(Unnormalized::skip_norm_wip) + { let predicate = replace_opaques_in(predicate, goals); // Require that the predicate holds for the concrete type. @@ -363,7 +366,9 @@ impl<'tcx> InferCtxt<'tcx> { // If this opaque is being defined and it's conditionally const, if self.tcx.is_conditionally_const(def_id) { let item_bounds = tcx.explicit_implied_const_bounds(def_id); - for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { + for (predicate, _) in + item_bounds.iter_instantiated_copied(tcx, args).map(Unnormalized::skip_norm_wip) + { let predicate = replace_opaques_in( predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe), goals, diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index 79d94982b1621..a550621a82d60 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -1,5 +1,6 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + Unnormalized, }; use crate::infer::outlives::test_type_match; @@ -61,6 +62,7 @@ where let outlives_bounds: Vec<_> = tcx .item_bounds(kind.def_id()) .iter_instantiated(tcx, args) + .map(Unnormalized::skip_norm_wip) .chain(param_env.caller_bounds()) .filter_map(|clause| { let outlives = clause.as_type_outlives_clause()?; diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index a5ba219f8e8ab..d0d1df6f04462 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,7 +1,7 @@ use std::assert_matches; use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive}; -use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt, Unnormalized}; use smallvec::smallvec; use tracing::{debug, instrument, trace}; @@ -285,6 +285,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { trace!("{:#?}", bounds.skip_binder()); bounds .iter_instantiated(tcx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) .filter_map(|p| p.as_type_outlives_clause()) .filter_map(|p| p.no_bound_vars()) .map(|OutlivesPredicate(_, r)| r) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 6461fbe0d33bb..49e8d9a1f44fb 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashSet; pub use rustc_middle::ty::elaborate::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt, Unnormalized}; use rustc_span::{Ident, Span}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; @@ -123,6 +123,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( stack.extend( tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name)) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref)) .filter_map(|clause| clause.as_trait_clause()) .filter(|clause| clause.polarity() == ty::PredicatePolarity::Positive) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 23a055e1e26f4..5d6b53547590b 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1164,7 +1164,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // Eagerly check the unsubstituted layout for cycles. tcx.ensure_ok().layout_of( ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) - .as_query_input(tcx.type_of(def_id).instantiate_identity()), + .as_query_input(tcx.type_of(def_id).instantiate_identity().skip_norm_wip()), ); } }); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 66082d782e0bb..3007f4cda92b9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -33,7 +33,9 @@ use rustc_middle::bug; use rustc_middle::lint::LevelAndSource; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; +use rustc_middle::ty::{ + self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, VariantDef, +}; // hardwired lints from rustc_lint_defs pub use rustc_session::lint::builtin::*; use rustc_session::lint::fcw; @@ -467,7 +469,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { // If the method is an impl for an item with docs_hidden, don't doc. AssocContainer::InherentImpl => { let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()); - let impl_ty = cx.tcx.type_of(parent).instantiate_identity(); + let impl_ty = cx.tcx.type_of(parent).instantiate_identity().skip_norm_wip(); let outerdef = match impl_ty.kind() { ty::Adt(def, _) => Some(def.did()), ty::Foreign(def_id) => Some(*def_id), @@ -576,7 +578,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { // and recommending Copy might be a bad idea. for field in def.all_fields() { let did = field.did; - if cx.tcx.type_of(did).instantiate_identity().is_raw_ptr() { + if cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().is_raw_ptr() { return; } } @@ -706,7 +708,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { let has_impl = cx .tcx - .non_blanket_impls_for_ty(debug, cx.tcx.type_of(item.owner_id).instantiate_identity()) + .non_blanket_impls_for_ty( + debug, + cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(), + ) .next() .is_some(); if !has_impl { @@ -1379,7 +1384,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { // FIXME(generic_const_exprs): Revisit this before stabilization. // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. - let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) && cx.tcx.features().generic_const_exprs() { @@ -2526,7 +2531,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { ty: Ty<'tcx>, init: InitKind, ) -> Option { - let ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty); + let ty = cx + .tcx + .try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)) + .unwrap_or(ty); match ty.kind() { // Primitive types that don't like 0 as a value. diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index acfa3ec343975..46aeec65fe2d7 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -24,7 +24,9 @@ use rustc_middle::lint::LevelAndSource; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; -use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode}; +use rustc_middle::ty::{ + self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode, Unnormalized, +}; use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintExpectationId, LintId}; use rustc_session::{DynLintStore, Session}; use rustc_span::edit_distance::find_best_match_for_names; @@ -833,7 +835,8 @@ impl<'tcx> LateContext<'tcx> { .find_by_ident_and_kind(tcx, Ident::with_dummy_span(name), ty::AssocTag::Type, trait_id) .and_then(|assoc| { let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]); - tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok() + tcx.try_normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(proj)) + .ok() }) } diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index d162ae4b77647..e57c0d806ded4 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -102,8 +102,8 @@ impl<'tcx> LateLintPass<'tcx> for DanglingPointers { && let TyKind::Ptr(_) = ret_ty.kind { // get the return type of the function or closure - let ty = match cx.tcx.type_of(def_id).instantiate_identity().kind() { - ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity(), + let ty = match cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() { + ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(), ty::Closure(_, args) => args.as_closure().sig(), _ => return, }; diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 9d4b79a45453a..825888f2810ca 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { // We don't care about what `#[derive(Default)]` produces in this lint. return; } - let ty = cx.tcx.type_of(impl_id).instantiate_identity(); + let ty = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip(); let ty::Adt(def, _) = ty.kind() else { return }; // We now know we have a manually written definition of a `::default()`. diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 3e1a418c8c962..5d487ddfe25b8 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { && let Some(did) = of_trait.trait_ref.trait_def_id() && tcx.is_lang_item(did, LangItem::Deref) // the self type is `dyn t_principal` - && let self_ty = tcx.type_of(item.owner_id).instantiate_identity() + && let self_ty = tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let ty::Dynamic(data, _) = self_ty.kind() && let Some(self_principal) = data.principal() // `::Target` is `dyn target_principal` diff --git a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs index 2a572a5a76bdb..7b8c582936149 100644 --- a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs +++ b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs @@ -48,7 +48,9 @@ fn path_for_rustc_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Optio return Some(format!("{}{}", name, gen_args(cx, path_segment))); } Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { - if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { + if let ty::Adt(adt, args) = + cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().kind() + { if find_attr!(cx.tcx, adt.did(), RustcPassByValue(_)) { return Some(cx.tcx.def_path_str_with_args(adt.did(), args)); } diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 9bc04db5e790b..21c3438aeda73 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -123,7 +123,7 @@ impl ClashingExternDeclarations { let Some(existing_did) = self.insert(tcx, this_fi) else { return }; let existing_decl_ty = tcx.type_of(existing_did).skip_binder(); - let this_decl_ty = tcx.type_of(this_fi.owner_id).instantiate_identity(); + let this_decl_ty = tcx.type_of(this_fi.owner_id).instantiate_identity().skip_norm_wip(); debug!( "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}", existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty @@ -297,8 +297,8 @@ fn structurally_same_type_impl<'tcx>( seen_types, tcx, typing_env, - tcx.type_of(a_did).instantiate(tcx, a_gen_args), - tcx.type_of(b_did).instantiate(tcx, b_gen_args), + tcx.type_of(a_did).instantiate(tcx, a_gen_args).skip_norm_wip(), + tcx.type_of(b_did).instantiate(tcx, b_gen_args).skip_norm_wip(), ) }, ) diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs index ae62bfbba2969..d24e934fc06fe 100644 --- a/compiler/rustc_lint/src/gpukernel_abi.rs +++ b/compiler/rustc_lint/src/gpukernel_abi.rs @@ -166,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperGpuKernelLint { return; } - let sig = cx.tcx.fn_sig(id).instantiate_identity(); + let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip(); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index e3a7be02fca51..65dfa8b93de78 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::relate::{ }; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint::fcw; @@ -141,7 +142,7 @@ enum ParamKind { } fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { - let sig = tcx.fn_sig(parent_def_id).instantiate_identity(); + let sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip(); let mut in_scope_parameters = FxIndexMap::default(); // Populate the in_scope_parameters list first with all of the generics in scope @@ -246,7 +247,7 @@ where && self.tcx.is_impl_trait_in_trait(def_id) { // visit the opaque of the RPITIT - self.tcx.type_of(def_id).instantiate(self.tcx, args).visit_with(self) + self.tcx.type_of(def_id).instantiate(self.tcx, args).skip_norm_wip().visit_with(self) } else if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args: opaque_ty_args, .. }) = *t.kind() && let Some(opaque_def_id) = def_id.as_local() // Don't recurse infinitely on an opaque @@ -412,7 +413,12 @@ where // in this lint as well. Interestingly, one place that I expect this lint to fire // is for `impl for<'a> Bound`, since `impl Other` will begin // to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed). - for clause in self.tcx.item_bounds(def_id).iter_instantiated(self.tcx, opaque_ty_args) { + for clause in self + .tcx + .item_bounds(def_id) + .iter_instantiated(self.tcx, opaque_ty_args) + .map(Unnormalized::skip_norm_wip) + { clause.visit_with(self) } } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index d637390851d9d..dc7cb1270f902 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -141,7 +141,7 @@ fn has_unstable_into_iter_predicate<'tcx>( } // `IntoIterator::into_iter` has no additional method args. let into_iter_fn_args = - cx.tcx.instantiate_bound_regions_with_erased(trait_pred).trait_ref.args; + cx.tcx.instantiate_bound_regions_with_erased(trait_pred.skip_norm_wip()).trait_ref.args; let Ok(Some(instance)) = ty::Instance::try_resolve( cx.tcx, cx.typing_env(), @@ -292,7 +292,8 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &hir::Path<'_>) -> Option { - if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() + if let ty::Adt(adt, args) = + cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().kind() && let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) { return Some(format!("{}<{}>", name, args[0])); diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 9177e00d902c8..9f2c2058998e1 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -1,4 +1,5 @@ use rustc_hir as hir; +use rustc_middle::ty::Unnormalized; use rustc_session::{declare_lint, declare_lint_pass}; use crate::{LateContext, LateLintPass, LintContext}; @@ -46,6 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .tcx .explicit_super_predicates_of(def_id) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .filter_map(|(pred, _)| pred.as_trait_clause()) .filter(|pred| !cx.tcx.is_lang_item(pred.def_id(), hir::LangItem::MetaSized)) .filter(|pred| !cx.tcx.is_default_trait(pred.def_id())); diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 66b4e3c16e936..8c0228101133a 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -1,6 +1,7 @@ use rustc_hir::def::DefKind; use rustc_hir::{Expr, ExprKind}; use rustc_middle::ty; +use rustc_middle::ty::Unnormalized; use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::sym; @@ -92,9 +93,10 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { return; }; - let args = cx - .tcx - .normalize_erasing_regions(cx.typing_env(), cx.typeck_results().node_args(expr.hir_id)); + let args = cx.tcx.normalize_erasing_regions( + cx.typing_env(), + Unnormalized::new_wip(cx.typeck_results().node_args(expr.hir_id)), + ); // Resolve the trait method instance. let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else { return; diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index b45f92285b81f..6947ff9d2c40b 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -2,7 +2,7 @@ use rustc_hir::{self as hir, AmbigArg}; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath}; -use rustc_middle::ty::{self, BottomUpFolder, Ty, TypeFoldable}; +use rustc_middle::ty::{self, BottomUpFolder, Ty, TypeFoldable, Unnormalized}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{Span, kw}; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -88,7 +88,12 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).iter_identity_copied() { + for (pred, pred_span) in cx + .tcx + .explicit_item_bounds(def_id) + .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) + { infcx.enter_forall(pred.kind(), |predicate| { let ty::ClauseKind::Projection(proj) = predicate else { return; @@ -146,12 +151,16 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { .tcx .explicit_item_bounds(proj.projection_term.def_id) .iter_instantiated_copied(cx.tcx, proj.projection_term.args) + .map(Unnormalized::skip_norm_wip) { let assoc_pred = assoc_pred.fold_with(proj_replacer); let ocx = ObligationCtxt::new(infcx); - let assoc_pred = - ocx.normalize(&traits::ObligationCause::dummy(), cx.param_env, assoc_pred); + let assoc_pred = ocx.normalize( + &traits::ObligationCause::dummy(), + cx.param_env, + Unnormalized::new_wip(assoc_pred), + ); if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { // Can't normalize for some reason...? continue; diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 2daf2a150354e..f15473ec19554 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_hir::{Expr, ExprKind, HirId, LangItem, find_attr}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::{Span, Symbol, sym}; use tracing::debug; @@ -698,7 +698,7 @@ pub(crate) fn transparent_newtype_field<'a, 'tcx>( ) -> Option<&'a ty::FieldDef> { let typing_env = ty::TypingEnv::non_body_analysis(tcx, variant.def_id); variant.fields.iter().find(|field| { - let field_ty = tcx.type_of(field.did).instantiate_identity(); + let field_ty = tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); let is_1zst = tcx.layout_of(typing_env.as_query_input(field_ty)).is_ok_and(|layout| layout.is_1zst()); !is_1zst @@ -711,7 +711,7 @@ fn ty_is_known_nonnull<'tcx>( typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> bool { - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); match ty.kind() { ty::FnPtr(..) => true, @@ -773,7 +773,7 @@ fn get_nullable_type<'tcx>( typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, ) -> Option> { - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); Some(match *ty.kind() { ty::Adt(field_def, field_args) => { @@ -936,7 +936,7 @@ declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]); impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { if let hir::ItemKind::Enum(_, _, ref enum_definition) = it.kind { - let t = cx.tcx.type_of(it.owner_id).instantiate_identity(); + let t = cx.tcx.type_of(it.owner_id).instantiate_identity().skip_norm_wip(); let ty = cx.tcx.erase_and_anonymize_regions(t); let Ok(layout) = cx.layout_of(ty) else { return }; let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, variants, .. } = @@ -1042,7 +1042,7 @@ impl InvalidAtomicOrdering { && let Some(m_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) // skip extension traits, only lint functions from the standard library && let Some(impl_did) = cx.tcx.inherent_impl_of_assoc(m_def_id) - && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() + && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().skip_norm_wip().ty_adt_def() && cx.tcx.is_diagnostic_item(sym::Atomic, adt.did()) { return Some((method_path.ident.name, args)); diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 38f2fbb07ed3e..c73d9911a6e29 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -11,7 +11,7 @@ use rustc_hir::{self as hir, AmbigArg}; use rustc_middle::bug; use rustc_middle::ty::{ self, Adt, AdtDef, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, + TypeVisitableExt, Unnormalized, }; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::def_id::LocalDefId; @@ -198,7 +198,7 @@ fn check_arg_for_power_alignment<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> // report if any fields after the nested struct within the // original struct are misaligned. for struct_field in &struct_variant.fields { - let field_ty = tcx.type_of(struct_field.did).instantiate_identity(); + let field_ty = tcx.type_of(struct_field.did).instantiate_identity().skip_norm_wip(); if check_arg_for_power_alignment(cx, field_ty) { return true; } @@ -235,7 +235,7 @@ fn check_struct_for_power_alignment<'tcx>( // Struct fields (after the first field) are checked for the // power alignment rule, as fields after the first are likely // to be the fields that are misaligned. - let ty = tcx.type_of(field_def.def_id).instantiate_identity(); + let ty = tcx.type_of(field_def.def_id).instantiate_identity().skip_norm_wip(); if check_arg_for_power_alignment(cx, ty) { cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment); } @@ -376,7 +376,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let field_ty = self .cx .tcx - .try_normalize_erasing_regions(self.cx.typing_env(), field_ty) + .try_normalize_erasing_regions(self.cx.typing_env(), Unnormalized::new_wip(field_ty)) .unwrap_or(field_ty); self.visit_type(state, field_ty) } @@ -726,7 +726,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if let Some(ty) = self .cx .tcx - .try_normalize_erasing_regions(self.cx.typing_env(), ty) + .try_normalize_erasing_regions(self.cx.typing_env(), Unnormalized::new_wip(ty)) .unwrap_or(ty) .visit_with(&mut ProhibitOpaqueTypes) .break_value() @@ -760,7 +760,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return res; } - let ty = self.cx.tcx.try_normalize_erasing_regions(self.cx.typing_env(), ty).unwrap_or(ty); + let ty = self + .cx + .tcx + .try_normalize_erasing_regions(self.cx.typing_env(), Unnormalized::new_wip(ty)) + .unwrap_or(ty); // C doesn't really support passing arrays by value - the only way to pass an array by value // is through a struct. So, first test that the top level isn't an array, and then @@ -848,7 +852,7 @@ impl<'tcx> ImproperCTypesLint { def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>, ) { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { @@ -880,7 +884,7 @@ impl<'tcx> ImproperCTypesLint { } fn check_foreign_static(&mut self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) { - let ty = cx.tcx.type_of(id).instantiate_identity(); + let ty = cx.tcx.type_of(id).instantiate_identity().skip_norm_wip(); let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); let ffi_res = visitor.check_type(VisitorState::STATIC_TY, ty); self.process_ffi_result(cx, span, ffi_res, CItemKind::Declaration); @@ -894,7 +898,7 @@ impl<'tcx> ImproperCTypesLint { def_id: LocalDefId, decl: &'tcx hir::FnDecl<'_>, ) { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { @@ -1008,7 +1012,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint { cx, VisitorState::STATIC_TY, ty, - cx.tcx.type_of(item.owner_id).instantiate_identity(), + cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(), CItemKind::Definition, ); } @@ -1042,7 +1046,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesLint { cx, VisitorState::STATIC_TY, field.ty, - cx.tcx.type_of(field.def_id).instantiate_identity(), + cx.tcx.type_of(field.def_id).instantiate_identity().skip_norm_wip(), CItemKind::Definition, ); } diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index 5bbe84a51fa2f..b2787bf54f9ac 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -5,7 +5,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_infer::traits::util::elaborate; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, Unnormalized}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{Span, Symbol, sym}; use tracing::instrument; @@ -208,23 +208,27 @@ pub fn is_ty_must_use<'tcx>( kind: ty::Opaque { def_id: def } | ty::Projection { def_id: def }, .. }) => { - elaborate(cx.tcx, cx.tcx.explicit_item_self_bounds(def).iter_identity_copied()) - // We only care about self bounds for the impl-trait - .filter_only_self() - .find_map(|(pred, _span)| { - // We only look at the `DefId`, so it is safe to skip the binder here. - if let ty::ClauseKind::Trait(ref poly_trait_predicate) = - pred.kind().skip_binder() - { - let def_id = poly_trait_predicate.trait_ref.def_id; - - is_def_must_use(cx, def_id, expr.span) - } else { - None - } - }) - .map(|inner| MustUsePath::Opaque(Box::new(inner))) - .map_or(IsTyMustUse::No, IsTyMustUse::Yes) + elaborate( + cx.tcx, + cx.tcx + .explicit_item_self_bounds(def) + .iter_identity_copied() + .map(Unnormalized::skip_norm_wip), + ) + // We only care about self bounds for the impl-trait + .filter_only_self() + .find_map(|(pred, _span)| { + // We only look at the `DefId`, so it is safe to skip the binder here. + if let ty::ClauseKind::Trait(ref poly_trait_predicate) = pred.kind().skip_binder() { + let def_id = poly_trait_predicate.trait_ref.def_id; + + is_def_must_use(cx, def_id, expr.span) + } else { + None + } + }) + .map(|inner| MustUsePath::Opaque(Box::new(inner))) + .map_or(IsTyMustUse::No, IsTyMustUse::Yes) } ty::Dynamic(binders, _) => binders .iter() diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 6b2d849a636ce..b64cb8843ed71 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -363,6 +363,7 @@ impl<'tcx> Collector<'tcx> { self.tcx .type_of(item) .instantiate_identity() + .skip_norm_wip() .fn_sig(self.tcx) .inputs() .map_bound(|slice| self.tcx.mk_type_list(slice)), @@ -408,8 +409,13 @@ impl<'tcx> Collector<'tcx> { // `__stdcall` only applies on x86 and on non-variadic functions: // https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170 ExternAbi::System { .. } => { - let c_variadic = - self.tcx.type_of(item).instantiate_identity().fn_sig(self.tcx).c_variadic(); + let c_variadic = self + .tcx + .type_of(item) + .instantiate_identity() + .skip_norm_wip() + .fn_sig(self.tcx) + .c_variadic(); if c_variadic { DllCallingConvention::C @@ -475,7 +481,7 @@ impl<'tcx> Collector<'tcx> { // We cannot determine the size of a function at compile time, but it shouldn't matter anyway. DllImportSymbolType::Function => rustc_abi::Size::ZERO, DllImportSymbolType::Static | DllImportSymbolType::ThreadLocal => { - let ty = self.tcx.type_of(item).instantiate_identity(); + let ty = self.tcx.type_of(item).instantiate_identity().skip_norm_wip(); self.tcx .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .ok() diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b516470052c3f..ece9dc52c292c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2183,7 +2183,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.defaultness.set(def_id.index, tcx.defaultness(def_id)); - let trait_ref = header.trait_ref.instantiate_identity(); + let trait_ref = header.trait_ref.instantiate_identity().skip_norm_wip(); let simplified_self_ty = fast_reject::simplify_type( self.tcx, trait_ref.self_ty(), diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f66c4755de4dd..c55d49c12b4b8 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -629,7 +629,7 @@ impl<'tcx> Operand<'tcx> { args: &[GenericArg<'tcx>], span: Span, ) -> Self { - let const_ = Const::from_unevaluated(tcx, def_id).instantiate(tcx, args); + let const_ = Const::from_unevaluated(tcx, def_id).instantiate(tcx, args).skip_norm_wip(); Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) } @@ -819,7 +819,9 @@ impl<'tcx> Rvalue<'tcx> { AggregateKind::Tuple => { Ty::new_tup_from_iter(tcx, ops.iter().map(|op| op.ty(local_decls, tcx))) } - AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args), + AggregateKind::Adt(did, _, args, _, _) => { + tcx.type_of(did).instantiate(tcx, args).skip_norm_wip() + } AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args), AggregateKind::Coroutine(did, args) => Ty::new_coroutine(tcx, did, args), AggregateKind::CoroutineClosure(did, args) => { diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index c501682775524..0c37971ba8552 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -248,7 +248,9 @@ pub fn ancestors( ) -> Result, ErrorGuaranteed> { let specialization_graph = tcx.specialization_graph_of(trait_def_id)?; - if let Err(reported) = tcx.type_of(start_from_impl).instantiate_identity().error_reported() { + if let Err(reported) = + tcx.type_of(start_from_impl).instantiate_identity().skip_norm_wip().error_reported() + { Err(reported) } else { Ok(Ancestors { diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 463e4c5880556..d80c4c73cb483 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -56,7 +56,7 @@ impl<'tcx> TyCtxt<'tcx> { Err(e) => ty::Const::new_error(self.tcx, e), Ok(Some(bac)) => { let args = self.tcx.erase_and_anonymize_regions(uv.args); - let bac = bac.instantiate(self.tcx, args); + let bac = bac.instantiate(self.tcx, args).skip_norm_wip(); return bac.fold_with(self); } Ok(None) => c, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b908a6c6e8439..450f2fbe92ca8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1617,7 +1617,8 @@ impl<'tcx> TyCtxt<'tcx> { self, self.lifetimes.re_static, self.type_of(self.require_lang_item(LangItem::PanicLocation, DUMMY_SP)) - .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])), + .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])) + .skip_norm_wip(), ) } @@ -2767,7 +2768,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool { if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = self.coroutine_kind(def_id) - && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind() + && let ty::Coroutine(_, args) = + self.type_of(def_id).instantiate_identity().skip_norm_wip().kind() && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce) { true diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 9913261b14d95..7e6f1fc3fd4c6 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -10,7 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; -use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph}; +use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, Unnormalized, search_graph}; use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::infer::canonical::CanonicalVarKinds; @@ -353,7 +353,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> { def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { ty::EarlyBinder::bind( - self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), + self.predicates_of(def_id) + .instantiate_identity(self) + .predicates + .into_iter() + .map(Unnormalized::skip_normalization), ) } @@ -362,7 +366,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> { def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { ty::EarlyBinder::bind( - self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause), + self.predicates_of(def_id) + .instantiate_own_identity() + .map(|(clause, _)| clause.skip_normalization()), ) } @@ -415,7 +421,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { ty::EarlyBinder::bind( - self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c), + self.const_conditions(def_id) + .instantiate_identity(self) + .into_iter() + .map(|(c, _)| c.skip_normalization()), ) } @@ -424,7 +433,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { ty::EarlyBinder::bind( - self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), + self.explicit_implied_const_bounds(def_id) + .iter_identity_copied() + .map(Unnormalized::skip_normalization) + .map(|(c, _)| c), ) } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 7bb5f673adf15..a43a0c687261a 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -629,7 +629,7 @@ impl<'tcx> TypeVisitor> for IsSuggestableVisitor<'tcx> { Alias(AliasTy { kind: Opaque { def_id }, .. }) => { let parent = self.tcx.parent(def_id); - let parent_ty = self.tcx.type_of(parent).instantiate_identity(); + let parent_ty = self.tcx.type_of(parent).instantiate_identity().skip_norm_wip(); if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent) && let Alias(AliasTy { kind: Opaque { def_id: parent_opaque_def_id }, .. }) = *parent_ty.kind() @@ -696,9 +696,10 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { let t = match *t.kind() { Infer(InferTy::TyVar(_)) if self.infer_suggestable => t, - FnDef(def_id, args) if self.placeholder.is_none() => { - Ty::new_fn_ptr(self.tcx, self.tcx.fn_sig(def_id).instantiate(self.tcx, args)) - } + FnDef(def_id, args) if self.placeholder.is_none() => Ty::new_fn_ptr( + self.tcx, + self.tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip(), + ), Closure(..) | CoroutineClosure(..) @@ -716,7 +717,7 @@ impl<'tcx> FallibleTypeFolder> for MakeSuggestableFolder<'tcx> { Alias(AliasTy { kind: Opaque { def_id }, .. }) => { let parent = self.tcx.parent(def_id); - let parent_ty = self.tcx.type_of(parent).instantiate_identity(); + let parent_ty = self.tcx.type_of(parent).instantiate_identity().skip_norm_wip(); if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) && let Alias(AliasTy { kind: Opaque { def_id: parent_opaque_def_id }, .. }) = diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 11a236f314c26..fd6078942e3ce 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -5,7 +5,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; use rustc_span::{Span, Symbol, kw}; use tracing::instrument; -use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt}; +use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt, Unnormalized}; use crate::ty; use crate::ty::{EarlyBinder, GenericArgsRef}; @@ -304,7 +304,7 @@ impl<'tcx> Generics { .rev() .take_while(|param| { param.default_value(tcx).is_some_and(|default| { - default.instantiate(tcx, args) == args[param.index as usize] + default.instantiate(tcx, args).skip_norm_wip() == args[param.index as usize] }) }) .count(); @@ -334,8 +334,9 @@ impl<'tcx> Generics { ) -> bool { let mut default_param_seen = false; for param in self.own_params.iter() { - if let Some(inst) = - param.default_value(tcx).map(|default| default.instantiate(tcx, args)) + if let Some(inst) = param + .default_value(tcx) + .map(|default| default.instantiate(tcx, args).skip_norm_wip()) { if inst == args[param.index as usize] { default_param_seen = true; @@ -382,14 +383,24 @@ impl<'tcx> GenericPredicates<'tcx> { self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator { - EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) + ) -> impl Iterator>, Span)> + + DoubleEndedIterator + + ExactSizeIterator { + EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args).map(|u| { + let (clause, span) = u.unzip(); + (clause, span.skip_normalization()) + }) } pub fn instantiate_own_identity( self, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator { - EarlyBinder::bind(self.predicates).iter_identity_copied() + ) -> impl Iterator>, Span)> + + DoubleEndedIterator + + ExactSizeIterator { + EarlyBinder::bind(self.predicates).iter_identity_copied().map(|u| { + let (clause, span) = u.unzip(); + (clause, span.skip_normalization()) + }) } #[instrument(level = "debug", skip(self, tcx))] @@ -422,7 +433,7 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p)); + instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| Unnormalized::new(*p))); instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } } @@ -442,7 +453,7 @@ impl<'tcx> ConstConditions<'tcx> { self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + ) -> Vec<(Unnormalized<'tcx, ty::PolyTraitRef<'tcx>>, Span)> { let mut instantiated = vec![]; self.instantiate_into(tcx, &mut instantiated, args); instantiated @@ -452,23 +463,31 @@ impl<'tcx> ConstConditions<'tcx> { self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator - { - EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) + ) -> impl Iterator>, Span)> + + DoubleEndedIterator + + ExactSizeIterator { + EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args).map(|u| { + let (trait_ref, span) = u.unzip(); + (trait_ref, span.skip_normalization()) + }) } pub fn instantiate_own_identity( self, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator - { - EarlyBinder::bind(self.predicates).iter_identity_copied() + ) -> impl Iterator>, Span)> + + DoubleEndedIterator + + ExactSizeIterator { + EarlyBinder::bind(self.predicates).iter_identity_copied().map(|u| { + let (trait_ref, span) = u.unzip(); + (trait_ref, span.skip_normalization()) + }) } #[instrument(level = "debug", skip(self, tcx))] fn instantiate_into( self, tcx: TyCtxt<'tcx>, - instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + instantiated: &mut Vec<(Unnormalized<'tcx, ty::PolyTraitRef<'tcx>>, Span)>, args: GenericArgsRef<'tcx>, ) { if let Some(def_id) = self.parent { @@ -479,7 +498,10 @@ impl<'tcx> ConstConditions<'tcx> { ); } - pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + pub fn instantiate_identity( + self, + tcx: TyCtxt<'tcx>, + ) -> Vec<(Unnormalized<'tcx, ty::PolyTraitRef<'tcx>>, Span)> { let mut instantiated = vec![]; self.instantiate_identity_into(tcx, &mut instantiated); instantiated @@ -488,11 +510,16 @@ impl<'tcx> ConstConditions<'tcx> { fn instantiate_identity_into( self, tcx: TyCtxt<'tcx>, - instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + instantiated: &mut Vec<(Unnormalized<'tcx, ty::PolyTraitRef<'tcx>>, Span)>, ) { if let Some(def_id) = self.parent { tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.extend(self.predicates.iter().copied()); + instantiated.extend( + self.predicates + .iter() + .copied() + .map(|(trait_ref, span)| (Unnormalized::new(trait_ref), span)), + ); } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index c935869b504cd..2a7c9e0372ca0 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -2,7 +2,7 @@ use rustc_macros::HashStable; use smallvec::SmallVec; use tracing::instrument; -use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TyCtxt, TypingEnv}; +use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TyCtxt, TypingEnv, Unnormalized}; /// Represents whether some type is inhabited in a given context. /// Examples of uninhabited types are `!`, `enum Void {}`, or a struct @@ -98,7 +98,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { // we have a param_env available, we can do better. Self::GenericType(t) => { let normalized_pred = tcx - .try_normalize_erasing_regions(typing_env, t) + .try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(t)) .map_or(self, |t| t.inhabited_predicate(tcx)); match normalized_pred { // We don't have more information than we started with, so consider inhabited. @@ -243,7 +243,7 @@ impl<'tcx> InhabitedPredicate<'tcx> { fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option { match self { Self::ConstIsZero(c) => { - let c = ty::EarlyBinder::bind(c).instantiate(tcx, args); + let c = ty::EarlyBinder::bind(c).instantiate(tcx, args).skip_norm_wip(); let pred = match c.try_to_target_usize(tcx) { Some(0) => Self::True, Some(1..) => Self::False, @@ -251,9 +251,12 @@ impl<'tcx> InhabitedPredicate<'tcx> { }; Some(pred) } - Self::GenericType(t) => { - Some(ty::EarlyBinder::bind(t).instantiate(tcx, args).inhabited_predicate(tcx)) - } + Self::GenericType(t) => Some( + ty::EarlyBinder::bind(t) + .instantiate(tcx, args) + .skip_norm_wip() + .inhabited_predicate(tcx), + ), Self::And(&[a, b]) => match a.instantiate_opt(tcx, args) { None => b.instantiate_opt(tcx, args).map(|b| a.and(tcx, b)), Some(InhabitedPredicate::False) => Some(InhabitedPredicate::False), diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 1f5edc031306c..6aff85e77da5a 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -82,7 +82,11 @@ impl<'tcx> VariantDef { InhabitedPredicate::all( tcx, self.fields.iter().map(|field| { - let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx); + let pred = tcx + .type_of(field.did) + .instantiate_identity() + .skip_norm_wip() + .inhabited_predicate(tcx); if adt.is_enum() { return pred; } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 9759e376c0586..408edf19dbf23 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -633,7 +633,7 @@ impl<'tcx> Instance<'tcx> { span: Span, ) -> Instance<'tcx> { debug!("resolve_for_vtable(def_id={:?}, args={:?})", def_id, args); - let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let is_vtable_shim = !fn_sig.inputs().skip_binder().is_empty() && fn_sig.input(0).skip_binder().is_param(0) && tcx.generics_of(def_id).has_self; @@ -863,9 +863,9 @@ impl<'tcx> Instance<'tcx> { { let v = v.map_bound(|v| *v); if let Some(args) = self.args_for_mir_body() { - v.instantiate(tcx, args) + v.instantiate(tcx, args).skip_norm_wip() } else { - v.instantiate_identity() + v.instantiate_identity().skip_norm_wip() } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 969d654941800..314481bef7a89 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -24,7 +24,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::TyCtxtAt; use crate::traits::ObligationCause; use crate::ty::normalize_erasing_regions::NormalizationError; -use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt}; +use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; #[extension(pub trait IntegerExt)] impl abi::Integer { @@ -370,7 +370,9 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_raw( pointee, &ObligationCause::dummy(), - |ty| match tcx.try_normalize_erasing_regions(typing_env, ty) { + |ty| match tcx + .try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) + { Ok(ty) => ty, Err(e) => Ty::new_error_with_message( tcx, @@ -500,7 +502,8 @@ impl<'tcx> SizeSkeleton<'tcx> { } ty::Alias(..) => { - let normalized = tcx.normalize_erasing_regions(typing_env, ty); + let normalized = + tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)); if ty == normalized { Err(err) } else { @@ -863,7 +866,11 @@ where { let metadata = tcx.normalize_erasing_regions( cx.typing_env(), - Ty::new_projection(tcx, metadata_def_id, [pointee]), + Unnormalized::new_wip(Ty::new_projection( + tcx, + metadata_def_id, + [pointee], + )), ); // Map `Metadata = DynMetadata` back to a vtable, since it diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0915cc48015c3..ddbeb25579e07 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -106,7 +106,7 @@ pub use self::sty::{ BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PlaceholderConst, PlaceholderRegion, PlaceholderType, PolyFnSig, TyKind, TypeAndMut, TypingMode, - TypingModeEqWrapper, UpvarArgs, + TypingModeEqWrapper, Unnormalized, UpvarArgs, }; pub use self::trait_def::TraitDef; pub use self::typeck_results::{ @@ -691,7 +691,7 @@ impl<'tcx> TermKind<'tcx> { /// [usize:Bar]]`. #[derive(Clone, Debug)] pub struct InstantiatedPredicates<'tcx> { - pub predicates: Vec>, + pub predicates: Vec>>, pub spans: Vec, } @@ -710,9 +710,12 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> { - type Item = (Clause<'tcx>, Span); + type Item = (Unnormalized<'tcx, Clause<'tcx>>, Span); - type IntoIter = std::iter::Zip>, std::vec::IntoIter>; + type IntoIter = std::iter::Zip< + std::vec::IntoIter>>, + std::vec::IntoIter, + >; fn into_iter(self) -> Self::IntoIter { debug_assert_eq!(self.predicates.len(), self.spans.len()); @@ -721,10 +724,10 @@ impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> { } impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { - type Item = (Clause<'tcx>, Span); + type Item = (Unnormalized<'tcx, Clause<'tcx>>, Span); type IntoIter = std::iter::Zip< - std::iter::Copied>>, + std::iter::Copied>>>, std::iter::Copied>, >; @@ -878,8 +881,8 @@ impl<'tcx> DefinitionSiteHiddenType<'tcx> { other: &Self, tcx: TyCtxt<'tcx>, ) -> Result, ErrorGuaranteed> { - let self_ty = self.ty.instantiate_identity(); - let other_ty = other.ty.instantiate_identity(); + let self_ty = self.ty.instantiate_identity().skip_norm_wip(); + let other_ty = other.ty.instantiate_identity().skip_norm_wip(); (self_ty, other_ty).error_reported()?; // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { @@ -1377,7 +1380,7 @@ impl<'tcx> FieldDef { /// Returns the type of this field. The resulting type is not normalized. The `arg` is /// typically obtained via the second field of [`TyKind::Adt`]. pub fn ty(&self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> { - tcx.type_of(self.did).instantiate(tcx, args) + tcx.type_of(self.did).instantiate(tcx, args).skip_norm_wip() } /// Computes the `Ident` of this variant by looking up the `Span` @@ -1777,7 +1780,7 @@ impl<'tcx> TyCtxt<'tcx> { // If we have a `Coroutine` that comes from an coroutine-closure, // then it may be a by-move or by-ref body. let ty::Coroutine(_, identity_args) = - *self.type_of(def_id).instantiate_identity().kind() + *self.type_of(def_id).instantiate_identity().skip_norm_wip().kind() else { unreachable!(); }; diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 69c1eb9b34543..b1cd53e25d2c0 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -13,7 +13,7 @@ use tracing::{debug, instrument}; use crate::traits::query::NoSolution; use crate::ty::{ self, EarlyBinder, FallibleTypeFolder, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeVisitableExt, + TypeVisitableExt, Unnormalized, }; #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)] @@ -38,10 +38,15 @@ impl<'tcx> TyCtxt<'tcx> { /// This should only be used outside of type inference. For example, /// it assumes that normalization will succeed. #[tracing::instrument(level = "debug", skip(self, typing_env), ret)] - pub fn normalize_erasing_regions(self, typing_env: ty::TypingEnv<'tcx>, value: T) -> T + pub fn normalize_erasing_regions( + self, + typing_env: ty::TypingEnv<'tcx>, + value: Unnormalized<'tcx, T>, + ) -> T where T: TypeFoldable>, { + let value = value.inside_norm(); debug!( "normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})", std::any::type_name::(), @@ -69,11 +74,12 @@ impl<'tcx> TyCtxt<'tcx> { pub fn try_normalize_erasing_regions( self, typing_env: ty::TypingEnv<'tcx>, - value: T, + value: Unnormalized<'tcx, T>, ) -> Result> where T: TypeFoldable>, { + let value = value.inside_norm(); debug!( "try_normalize_erasing_regions::<{}>(value={:?}, typing_env={:?})", std::any::type_name::(), @@ -115,7 +121,7 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable>, { let value = self.instantiate_bound_regions_with_erased(value); - self.normalize_erasing_regions(typing_env, value) + self.normalize_erasing_regions(typing_env, Unnormalized::new_wip(value)) } /// Monomorphizes a type from the AST by first applying the diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 3baeb7141de50..de5b18d2d91f9 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -430,7 +430,9 @@ impl<'tcx> Clause<'tcx> { let shifted_pred = tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder()); // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1> - let new = EarlyBinder::bind(shifted_pred).instantiate(tcx, trait_ref.skip_binder().args); + let new = EarlyBinder::bind(shifted_pred) + .instantiate(tcx, trait_ref.skip_binder().args) + .skip_norm_wip(); // 3) ['x] + ['b] -> ['x, 'b] let bound_vars = tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars)); diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 20e40dd6b2fe4..d2ae226c4d8dc 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -48,15 +48,17 @@ pub trait Printer<'tcx>: Sized { let impl_trait_ref = tcx.impl_opt_trait_ref(impl_def_id); let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() { ( - self_ty.instantiate(tcx, args), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args)), + self_ty.instantiate(tcx, args).skip_norm_wip(), + impl_trait_ref + .map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args).skip_norm_wip()), ) } else { // We are probably printing a nested item inside of an impl. // Use the identity substitutions for the impl. ( - self_ty.instantiate_identity(), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()), + self_ty.instantiate_identity().skip_norm_wip(), + impl_trait_ref + .map(|impl_trait_ref| impl_trait_ref.instantiate_identity().skip_norm_wip()), ) }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1262974325a1f..550e72a3a8717 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -17,7 +17,7 @@ use rustc_hir::limit::Limit; use rustc_macros::{Lift, extension}; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_span::{Ident, RemapPathScopeComponents, Symbol, kw, sym}; -use rustc_type_ir::{FieldInfo, Upcast as _, elaborate}; +use rustc_type_ir::{FieldInfo, Unnormalized, Upcast as _, elaborate}; use smallvec::SmallVec; // `pretty` is a separate module only for organization. @@ -746,7 +746,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if with_reduced_queries() { self.print_def_path(def_id, args)?; } else { - let mut sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args); + let mut sig = + self.tcx().fn_sig(def_id).instantiate(self.tcx(), args).skip_norm_wip(); if self.tcx().codegen_fn_attrs(def_id).safe_target_features { write!(self, "#[target_features] ")?; sig = sig.map_bound(|mut sig| { @@ -845,8 +846,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { DefKind::TyAlias | DefKind::AssocTy => { // NOTE: I know we should check for NO_QUERIES here, but it's alright. // `type_of` on a type alias or assoc type should never cause a cycle. - if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: d }, .. }) = - *self.tcx().type_of(parent).instantiate_identity().kind() + if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: d }, .. }) = *self + .tcx() + .type_of(parent) + .instantiate_identity() + .skip_norm_wip() + .kind() { if d == def_id { // If the type alias directly starts with the `impl` of the @@ -1085,7 +1090,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut has_negative_sized_bound = false; let mut has_meta_sized_bound = false; - for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { + for (predicate, _) in + bounds.iter_instantiated_copied(tcx, args).map(Unnormalized::skip_norm_wip) + { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs index ddce5342caffa..e680e62f50931 100644 --- a/compiler/rustc_middle/src/ty/significant_drop_order.rs +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -5,7 +5,7 @@ use rustc_span::Span; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, Unnormalized}; /// An additional filter to exclude well-known types from the ecosystem /// because their drops are trivial. @@ -80,7 +80,7 @@ pub fn extract_component_raw<'tcx>( ty_seen: &mut UnordSet>, ) -> SmallVec<[Ty<'tcx>; 4]> { // Droppiness does not depend on regions, so let us erase them. - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty)); debug!(?ty, "components"); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 9164f7b57e648..d4e3aaf3c6967 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -39,6 +39,7 @@ pub type AliasTyKind<'tcx> = ir::AliasTyKind>; pub type FnSig<'tcx> = ir::FnSig>; pub type Binder<'tcx, T> = ir::Binder, T>; pub type EarlyBinder<'tcx, T> = ir::EarlyBinder, T>; +pub type Unnormalized<'tcx, T> = ir::Unnormalized, T>; pub type TypingMode<'tcx> = ir::TypingMode>; pub type TypingModeEqWrapper<'tcx> = ir::TypingModeEqWrapper>; pub type Placeholder<'tcx, T> = ir::Placeholder, T>; @@ -157,7 +158,9 @@ impl<'tcx> ty::CoroutineArgs> { if tcx.is_async_drop_in_place_coroutine(def_id) { layout.field_tys[*field].ty } else { - ty::EarlyBinder::bind(layout.field_tys[*field].ty).instantiate(tcx, self.args) + ty::EarlyBinder::bind(layout.field_tys[*field].ty) + .instantiate(tcx, self.args) + .skip_norm_wip() } }) }) @@ -873,7 +876,7 @@ impl<'tcx> Ty<'tcx> { ty_param.into() } else { assert!(has_default); - tcx.type_of(param.def_id).instantiate(tcx, args).into() + tcx.type_of(param.def_id).instantiate(tcx, args).skip_norm_wip().into() } } }); @@ -1757,7 +1760,7 @@ impl<'tcx> Ty<'tcx> { ty::Dynamic(_, _) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP); - Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()])) + Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]).skip_norm_wip()) } // We don't know the metadata of `self`, but it must be equal to the @@ -1948,9 +1951,9 @@ impl<'tcx> Ty<'tcx> { ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)), - ty::Adt(def, args) => def - .sizedness_constraint(tcx, sizedness) - .is_none_or(|ty| ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness)), + ty::Adt(def, args) => def.sizedness_constraint(tcx, sizedness).is_none_or(|ty| { + ty.instantiate(tcx, args).skip_norm_wip().has_trivial_sizedness(tcx, sizedness) + }), ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index af5d81a108ba7..b8671c5d9633a 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -273,7 +273,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait for &impl_def_id in tcx.local_trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); - let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); + let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip(); if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::InstantiateWithInfer) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 95f75b473bf82..07baf5b49d659 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -28,7 +28,7 @@ use crate::traits::ObligationCause; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, - TypeFolder, TypeSuperFoldable, TypeVisitableExt, Upcast, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast, }; #[derive(Copy, Clone, Debug)] @@ -220,7 +220,7 @@ impl<'tcx> TyCtxt<'tcx> { tcx.struct_tail_raw( ty, &ObligationCause::dummy(), - |ty| tcx.normalize_erasing_regions(typing_env, ty), + |ty| tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)), || {}, ) } @@ -335,7 +335,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> (Ty<'tcx>, Ty<'tcx>) { let tcx = self; tcx.struct_lockstep_tails_raw(source, target, |ty| { - tcx.normalize_erasing_regions(typing_env, ty) + tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) }) } @@ -517,10 +517,14 @@ impl<'tcx> TyCtxt<'tcx> { // , and then look up which of the impl args refer to // parameters marked as pure. - let impl_args = match *self.type_of(impl_def_id).instantiate_identity().kind() { - ty::Adt(def_, args) if def_ == def => args, - _ => span_bug!(self.def_span(impl_def_id), "expected ADT for self type of `Drop` impl"), - }; + let impl_args = + match *self.type_of(impl_def_id).instantiate_identity().skip_norm_wip().kind() { + ty::Adt(def_, args) if def_ == def => args, + _ => span_bug!( + self.def_span(impl_def_id), + "expected ADT for self type of `Drop` impl" + ), + }; let item_args = ty::GenericArgs::identity_for_item(self, def.did()); @@ -724,7 +728,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the type a reference to the thread local takes in MIR. pub fn thread_local_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { - let static_ty = self.type_of(def_id).instantiate_identity(); + let static_ty = self.type_of(def_id).instantiate_identity().skip_norm_wip(); if self.is_mutable_static(def_id) { Ty::new_mut_ptr(self, static_ty) } else if self.is_foreign_item(def_id) { @@ -924,7 +928,7 @@ impl<'tcx> TyCtxt<'tcx> { return Ty::new_error(self, guar); } - ty = self.type_of(def_id).instantiate(self, args); + ty = self.type_of(def_id).instantiate(self, args).skip_norm_wip(); depth += 1; } @@ -987,7 +991,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { Some(expanded_ty) => *expanded_ty, None => { let generic_ty = self.tcx.type_of(def_id); - let concrete_ty = generic_ty.instantiate(self.tcx, args); + let concrete_ty = generic_ty.instantiate(self.tcx, args).skip_norm_wip(); let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, args), expanded_ty); expanded_ty @@ -1067,7 +1071,7 @@ impl<'tcx> TypeFolder> for FreeAliasTypeExpander<'tcx> { self.depth += 1; let ty = ensure_sufficient_stack(|| { - self.tcx.type_of(def_id).instantiate(self.tcx, args).fold_with(self) + self.tcx.type_of(def_id).instantiate(self.tcx, args).skip_norm_wip().fold_with(self) }); self.depth -= 1; ty @@ -1331,7 +1335,7 @@ impl<'tcx> Ty<'tcx> { // query keys used. If normalization fails, we just use `query_ty`. debug_assert!(!typing_env.param_env.has_infer()); let query_ty = tcx - .try_normalize_erasing_regions(typing_env, query_ty) + .try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(query_ty)) .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty)); tcx.needs_drop_raw(typing_env.as_query_input(query_ty)) @@ -1368,7 +1372,7 @@ impl<'tcx> Ty<'tcx> { // If normalization fails, we just use `query_ty`. debug_assert!(!typing_env.has_infer()); let query_ty = tcx - .try_normalize_erasing_regions(typing_env, query_ty) + .try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(query_ty)) .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(query_ty)); tcx.needs_async_drop_raw(typing_env.as_query_input(query_ty)) @@ -1411,7 +1415,7 @@ impl<'tcx> Ty<'tcx> { // This doesn't depend on regions, so try to minimize distinct // query keys used. // FIX: Use try_normalize to avoid crashing. If it fails, return true. - tcx.try_normalize_erasing_regions(typing_env, query_ty) + tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(query_ty)) .map(|erased| tcx.has_significant_drop_raw(typing_env.as_query_input(erased))) .unwrap_or(true) } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 01c1e2e79b501..70f6a4f83803b 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -480,7 +480,7 @@ fn construct_fn<'tcx>( let arguments = &thir.params; let return_ty = fn_sig.output(); - let coroutine = match tcx.type_of(fn_def).instantiate_identity().kind() { + let coroutine = match tcx.type_of(fn_def).instantiate_identity().skip_norm_wip().kind() { ty::Coroutine(_, args) => Some(Box::new(CoroutineInfo::initial( tcx.coroutine_kind(fn_def).unwrap(), args.as_coroutine().yield_ty(), @@ -622,16 +622,18 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - | DefKind::AnonConst | DefKind::InlineConst | DefKind::Static { .. } - | DefKind::GlobalAsm => (vec![], tcx.type_of(def_id).instantiate_identity(), None), + | DefKind::GlobalAsm => { + (vec![], tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), None) + } DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => { let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), - tcx.fn_sig(def_id).instantiate_identity(), + tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(), ); (sig.inputs().to_vec(), sig.output(), None) } DefKind::Closure => { - let closure_ty = tcx.type_of(def_id).instantiate_identity(); + let closure_ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); match closure_ty.kind() { ty::Closure(_, args) => { let args = args.as_closure(); @@ -855,9 +857,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://github.com/rust-lang/rust/issues/149571 && self .tcx - .fn_sig(self.def_id) - .instantiate_identity() - .skip_binder() + .fn_sig(self.def_id).instantiate_identity().skip_binder() .output() .is_inhabited_from( self.tcx, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index f22ff92c01782..399283c48f8b1 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -198,6 +198,7 @@ impl<'tcx> ThirBuildCx<'tcx> { self.tcx .type_of(va_list_did) .instantiate(self.tcx, &[self.tcx.lifetimes.re_erased.into()]) + .skip_norm_wip() } else { fn_sig.inputs()[index] }; diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index b0ccf1f85181d..8a34320990e19 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -992,7 +992,11 @@ fn find_fallback_pattern_typo<'tcx>( }; if let Some(value_ns) = path.res.value_ns && let Res::Def(DefKind::Const { .. }, id) = value_ns - && infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity()) + && infcx.can_eq( + param_env, + ty, + cx.tcx.type_of(id).instantiate_identity().skip_norm_wip(), + ) { if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) { // The original const is accessible, suggest using it directly. @@ -1009,7 +1013,11 @@ fn find_fallback_pattern_typo<'tcx>( } } if let DefKind::Const { .. } = cx.tcx.def_kind(item.owner_id) - && infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity()) + && infcx.can_eq( + param_env, + ty, + cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(), + ) { // Look for local consts. let item_name = cx.tcx.item_name(item.owner_id); diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 055d124386cf9..8a3f8108e0565 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -9,7 +9,7 @@ use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use tracing::debug; use crate::JoinSemiLattice; @@ -544,7 +544,9 @@ impl<'tcx> Map<'tcx> { break; } - if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, place_info.ty) { + if let Ok(ty) = + tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(place_info.ty)) + { place_info.ty = ty; } @@ -666,7 +668,9 @@ impl<'tcx> Map<'tcx> { return Some(value); } - if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, place_info.ty) { + if let Ok(ty) = + tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(place_info.ty)) + { place_info.ty = ty; } @@ -1067,7 +1071,7 @@ pub fn iter_fields<'tcx>( for (f_index, f_def) in v_def.fields.iter().enumerate() { let field_ty = f_def.ty(tcx, args); let field_ty = tcx - .try_normalize_erasing_regions(typing_env, field_ty) + .try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(field_ty)) .unwrap_or_else(|_| tcx.erase_and_anonymize_regions(field_ty)); f(variant, f_index.into(), field_ty); } diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs index cac6308617acf..b47e7bd168678 100644 --- a/compiler/rustc_mir_transform/src/check_call_recursion.rs +++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs @@ -6,7 +6,7 @@ use rustc_data_structures::graph::iterate::{ use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_middle::mir::{self, BasicBlock, BasicBlocks, Body, Terminator, TerminatorKind}; -use rustc_middle::ty::{self, GenericArg, GenericArgs, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericArg, GenericArgs, Instance, Ty, TyCtxt, Unnormalized}; use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION; use rustc_span::Span; @@ -45,9 +45,9 @@ impl<'tcx> MirLint<'tcx> for CheckDropRecursion { if let DefKind::AssocFn = tcx.def_kind(def_id) && let Some(impl_id) = tcx.trait_impl_of_assoc(def_id.to_def_id()) && let trait_ref = tcx.impl_trait_ref(impl_id) - && tcx.is_lang_item(trait_ref.instantiate_identity().def_id, LangItem::Drop) + && tcx.is_lang_item(trait_ref.instantiate_identity().skip_norm_wip().def_id, LangItem::Drop) // avoid erroneous `Drop` impls from causing ICEs below - && let sig = tcx.fn_sig(def_id).instantiate_identity() + && let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip() && sig.inputs().skip_binder().len() == 1 { // It was. Now figure out for what type `Drop` is implemented and then @@ -143,7 +143,9 @@ impl<'tcx> TerminatorClassifier<'tcx> for CallRecursion<'tcx> { let func_ty = func.ty(body, tcx); if let ty::FnDef(callee, args) = *func_ty.kind() { - let Ok(normalized_args) = tcx.try_normalize_erasing_regions(typing_env, args) else { + let Ok(normalized_args) = + tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(args)) + else { return false; }; let (callee, call_args) = if let Ok(Some(instance)) = diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index aa945266413d0..4158869f265b1 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -47,8 +47,8 @@ pub(super) fn is_inline_valid_on_fn<'tcx>( } let ty = tcx.type_of(def_id); - if match ty.instantiate_identity().kind() { - ty::FnDef(..) => tcx.fn_sig(def_id).instantiate_identity().c_variadic(), + if match ty.instantiate_identity().skip_norm_wip().kind() { + ty::FnDef(..) => tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().c_variadic(), ty::Closure(_, args) => args.as_closure().sig().c_variadic(), _ => false, } { diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 951ff69c19e3e..d17d188850412 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -110,7 +110,7 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>( let parent_def_id = tcx.local_parent(coroutine_def_id); let ty::CoroutineClosure(_, parent_args) = - *tcx.type_of(parent_def_id).instantiate_identity().kind() + *tcx.type_of(parent_def_id).instantiate_identity().skip_norm_wip().kind() else { bug!("coroutine's parent was not a coroutine-closure"); }; diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 644f2d22ef7ff..5d3827e70ffb1 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -58,7 +58,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return true; } - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); for ty in sig.inputs().skip_binder().iter().chain(std::iter::once(&sig.output().skip_binder())) { // FIXME(f16_f128): in order to avoid crashes building `core`, always inline to skip diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index ad94c23f229c4..cd6395eb2e8e8 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -188,7 +188,7 @@ pub(super) fn deduced_param_attrs<'tcx>( // Codegen won't use this information for anything if all the function parameters are passed // directly. Detect that and bail, for compilation speed. - let fn_ty = tcx.type_of(def_id).instantiate_identity(); + let fn_ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if matches!(fn_ty.kind(), ty::FnDef(..)) && fn_ty .fn_sig(tcx) diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index a8eb22b5c4e5c..b2c1314ec08b1 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -96,13 +96,17 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs { let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did; - let Some(unique_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def() else { + let Some(unique_def) = + tcx.type_of(unique_did).instantiate_identity().skip_norm_wip().ty_adt_def() + else { span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") }; let nonnull_did = unique_def.non_enum_variant().fields[FieldIdx::ZERO].did; - let Some(nonnull_def) = tcx.type_of(nonnull_did).instantiate_identity().ty_adt_def() else { + let Some(nonnull_def) = + tcx.type_of(nonnull_did).instantiate_identity().skip_norm_wip().ty_adt_def() + else { span_bug!(tcx.def_span(nonnull_did), "expected Unique to contain Nonnull") }; diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 3da9d6aac9be9..7193a0245d121 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -7,7 +7,7 @@ use rustc_index::Idx; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt, Unnormalized}; use rustc_middle::{bug, span_bug, traits}; use rustc_span::{DUMMY_SP, Spanned, dummy_spanned}; use tracing::{debug, instrument}; @@ -286,7 +286,7 @@ where // Resolving async_drop_in_place function for drop_ty let drop_fn_def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, span); let trait_args = tcx.mk_args(&[drop_ty.into()]); - let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args); + let sig = tcx.fn_sig(drop_fn_def_id).instantiate(tcx, trait_args).skip_norm_wip(); let sig = tcx.instantiate_bound_regions_with_erased(sig); (sig.output(), drop_fn_def_id, trait_args) }; @@ -562,7 +562,10 @@ where // We silently leave an unnormalized type here to support polymorphic drop // elaboration for users of rustc internal APIs let field_ty = tcx - .try_normalize_erasing_regions(self.elaborator.typing_env(), field_ty) + .try_normalize_erasing_regions( + self.elaborator.typing_env(), + Unnormalized::new_wip(field_ty), + ) .unwrap_or(field_ty); (tcx.mk_place_field(base_place, field_idx, field_ty), subpath) diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 0216e0d4cfbc5..71c9b79d682df 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -83,8 +83,9 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { // If the inner type matches the type bound by `Pointer` if inner_ty == bound_ty { // Do an instantiation using the parameters from the callsite - let instantiated_ty = - EarlyBinder::bind(inner_ty).instantiate(self.tcx, args_ref); + let instantiated_ty = EarlyBinder::bind(inner_ty) + .instantiate(self.tcx, args_ref) + .skip_norm_wip(); if let Some((fn_id, fn_args)) = FunctionItemRefChecker::is_fn_ref(instantiated_ty) { @@ -151,7 +152,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { .unwrap_crate_local() .lint_root; // FIXME: use existing printing routines to print the function signature - let fn_sig = self.tcx.fn_sig(fn_id).instantiate(self.tcx, fn_args); + let fn_sig = self.tcx.fn_sig(fn_id).instantiate(self.tcx, fn_args).skip_norm_wip(); let unsafety = fn_sig.safety().prefix_str(); let abi = match fn_sig.abi() { ExternAbi::Rust => String::from(""), diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index e9a20aa016550..88cef3e8560da 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -116,7 +116,7 @@ use rustc_middle::mir::interpret::{AllocRange, GlobalAlloc}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::layout::HasTypingEnv; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_span::DUMMY_SP; use smallvec::SmallVec; use tracing::{debug, instrument, trace}; @@ -1632,10 +1632,13 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx); if left_meta_ty == right_meta_ty { true - } else if let Ok(left) = - self.tcx.try_normalize_erasing_regions(self.typing_env(), left_meta_ty) - && let Ok(right) = - self.tcx.try_normalize_erasing_regions(self.typing_env(), right_meta_ty) + } else if let Ok(left) = self + .tcx + .try_normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(left_meta_ty)) + && let Ok(right) = self.tcx.try_normalize_erasing_regions( + self.typing_env(), + Unnormalized::new_wip(right_meta_ty), + ) { left == right } else { diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index 71e4d5581ddc2..88486f6baddad 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -27,7 +27,7 @@ //! it's usually never invoked in this way. use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind}; -use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt}; +use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized}; use rustc_span::def_id::DefId; use rustc_trait_selection::traits; use tracing::trace; @@ -39,14 +39,15 @@ pub(crate) struct ImpossiblePredicates; fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); tracing::trace!(?predicates); - let predicates = predicates.predicates.into_iter().filter(|p| { - !p.has_type_flags( - // Only consider global clauses to simplify. - TypeFlags::HAS_FREE_LOCAL_NAMES + let predicates = + predicates.predicates.into_iter().map(Unnormalized::skip_norm_wip).filter(|p| { + !p.has_type_flags( + // Only consider global clauses to simplify. + TypeFlags::HAS_FREE_LOCAL_NAMES // Clauses that refer to unevaluated constants as they cause cycles. | TypeFlags::HAS_CT_PROJECTION, - ) - }); + ) + }); let predicates: Vec<_> = traits::elaborate(tcx, predicates).collect(); tracing::trace!(?predicates); predicates.references_error() || traits::impossible_predicates(tcx, predicates) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index afcea3236dbda..db0eb56188255 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -13,7 +13,9 @@ use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; +use rustc_middle::ty::{ + self, Instance, InstanceKind, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized, +}; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::Spanned; use tracing::{debug, instrument, trace, trace_span}; @@ -560,7 +562,9 @@ fn resolve_callsite<'tcx, I: Inliner<'tcx>>( } // To resolve an instance its args have to be fully normalized. - let args = tcx.try_normalize_erasing_regions(inliner.typing_env(), args).ok()?; + let args = tcx + .try_normalize_erasing_regions(inliner.typing_env(), Unnormalized::new_wip(args)) + .ok()?; let callee = Instance::try_resolve(tcx, inliner.typing_env(), def_id, args).ok().flatten()?; @@ -572,7 +576,7 @@ fn resolve_callsite<'tcx, I: Inliner<'tcx>>( return None; } - let fn_sig = tcx.fn_sig(def_id).instantiate(tcx, args); + let fn_sig = tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(); // Additionally, check that the body that we're inlining actually agrees // with the ABI of the trait that the item comes from. diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 8d0922db8f40e..8beb00c5deffa 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -18,7 +18,7 @@ use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; -use rustc_middle::ty::{self, ConstInt, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, ConstInt, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::Span; use tracing::{debug, instrument, trace}; @@ -261,7 +261,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // that the `PostAnalysisNormalize` pass has happened and that the body's consts // are normalized, so any call to resolve before that needs to be // manually normalized. - let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?; + let val = self + .tcx + .try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(c.const_)) + .ok()?; self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))? .as_mplace_or_imm() diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 0ddb9157c7db1..256d511ecff7c 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -202,7 +202,7 @@ fn maybe_suggest_unit_pattern_typo<'tcx>( .hir_body_owners() .filter(|&def_id| { matches!(tcx.def_kind(def_id), DefKind::Const { .. }) - && tcx.type_of(def_id).instantiate_identity() == ty + && tcx.type_of(def_id).instantiate_identity().skip_norm_wip() == ty && tcx.visibility(def_id).is_accessible_from(body_def_id, tcx) }) .collect::>(); diff --git a/compiler/rustc_mir_transform/src/post_analysis_normalize.rs b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs index 5599dee4ccad3..776840a6fe8b2 100644 --- a/compiler/rustc_mir_transform/src/post_analysis_normalize.rs +++ b/compiler/rustc_mir_transform/src/post_analysis_normalize.rs @@ -4,7 +4,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; pub(super) struct PostAnalysisNormalize; @@ -63,7 +63,10 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.typing_env, constant.const_) { + if let Ok(c) = self + .tcx + .try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(constant.const_)) + { constant.const_ = c; } self.super_const_operand(constant, location); @@ -74,7 +77,9 @@ impl<'tcx> MutVisitor<'tcx> for PostAnalysisNormalizeVisitor<'tcx> { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.typing_env, *ty) { + if let Ok(t) = + self.tcx.try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(*ty)) + { *ty = t; } } diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index bebd8fab74565..dfdb8765475d9 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -13,7 +13,7 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveZsts { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Avoid query cycles (coroutines require optimized MIR for layout). - if tcx.type_of(body.source.def_id()).instantiate_identity().is_coroutine() { + if tcx.type_of(body.source.def_id()).instantiate_identity().skip_norm_wip().is_coroutine() { return; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4fd0629befecf..16c359d3eafa1 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::visit::{MutVisitor, PlaceContext}; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, + self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Span, Spanned, dummy_spanned}; @@ -141,7 +141,8 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceKind<'tcx>) -> Body< .unwrap() }; - let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args); + let mut body = + EarlyBinder::bind(body.clone()).instantiate(tcx, args).skip_norm_wip(); debug!("make_shim({:?}) = {:?}", instance, body); pm::run_passes( @@ -339,7 +340,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) } else { GenericArgs::identity_for_item(tcx, def_id) }; - let sig = tcx.fn_sig(def_id).instantiate(tcx, args); + let sig = tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(); let sig = tcx.instantiate_bound_regions_with_erased(sig); let span = tcx.def_span(def_id); @@ -570,7 +571,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must instantiate the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let sig = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]); + let sig = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).skip_norm_wip(); let sig = tcx.instantiate_bound_regions_with_erased(sig); let span = tcx.def_span(def_id); @@ -824,9 +825,9 @@ fn build_call_shim<'tcx>( assert_eq!(sig_args.is_some(), !instance.has_polymorphic_mir_body()); let mut sig = if let Some(sig_args) = sig_args { - sig.instantiate(tcx, &sig_args) + sig.instantiate(tcx, &sig_args).skip_norm_wip() } else { - sig.instantiate_identity() + sig.instantiate_identity().skip_norm_wip() }; if let CallKind::Indirect(fnty) = call_kind { @@ -912,7 +913,7 @@ fn build_call_shim<'tcx>( // `FnDef` call with optional receiver. CallKind::Direct(def_id) => { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); ( Operand::Constant(Box::new(ConstOperand { span, @@ -1036,9 +1037,10 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let sig = tcx .fn_sig(ctor_id) .instantiate_identity() + .skip_norm_wip() .no_bound_vars() .expect("LBR in ADT constructor signature"); - let sig = tcx.normalize_erasing_regions(typing_env, sig); + let sig = tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(sig)); let ty::Adt(adt_def, args) = sig.output().kind() else { bug!("unexpected type for ADT ctor {:?}", sig.output()); @@ -1111,7 +1113,9 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { assert_matches!(self_ty.kind(), ty::FnPtr(..), "expected fn ptr, found {self_ty}"); let span = tcx.def_span(def_id); - let Some(sig) = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).no_bound_vars() else { + let Some(sig) = + tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).skip_norm_wip().no_bound_vars() + else { span_bug!(span, "FnPtr::addr with bound vars for `{self_ty}`"); }; let locals = local_decls_for_sig(&sig, span); @@ -1143,7 +1147,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( coroutine_closure_def_id: DefId, receiver_by_ref: bool, ) -> Body<'tcx> { - let mut self_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity(); + let mut self_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity().skip_norm_wip(); let mut self_local: Place<'tcx> = Local::from_usize(1).into(); let ty::CoroutineClosure(_, args) = *self_ty.kind() else { bug!(); diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index a0f1260cd986d..41e8b1c88c4bc 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -20,7 +20,7 @@ pub(super) fn build_async_destructor_ctor_shim<'tcx>( debug_assert_eq!(Some(def_id), tcx.lang_items().async_drop_in_place_fn()); let generic_body = tcx.optimized_mir(def_id); let args = tcx.mk_args(&[ty.into()]); - let mut body = EarlyBinder::bind(generic_body.clone()).instantiate(tcx, args); + let mut body = EarlyBinder::bind(generic_body.clone()).instantiate(tcx, args).skip_norm_wip(); // Minimal shim passes except MentionedItems, // it causes error "mentioned_items for DefId(...async_drop_in_place...) have already been set @@ -212,7 +212,8 @@ fn build_adrop_for_coroutine_shim<'tcx>( // let mut _x: &mut CorLayout = &*_1.0.0; // Replace old _1.0 accesses into _x accesses; let body = tcx.optimized_mir(*coroutine_def_id).future_drop_poll().unwrap(); - let mut body: Body<'tcx> = EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args); + let mut body: Body<'tcx> = + EarlyBinder::bind(body.clone()).instantiate(tcx, impl_args).skip_norm_wip(); body.source.instance = instance; body.phase = MirPhase::Runtime(RuntimePhase::Initial); body.var_debug_info.clear(); diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index a6ed66c8427b3..f9ab5f3551221 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -24,7 +24,7 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates { debug!(def_id = ?body.source.def_id()); // Avoid query cycles (coroutines require optimized MIR for layout). - if tcx.type_of(body.source.def_id()).instantiate_identity().is_coroutine() { + if tcx.type_of(body.source.def_id()).instantiate_identity().skip_norm_wip().is_coroutine() { return; } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 697de3702b6ac..995a14c67e66c 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -14,7 +14,8 @@ use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance, + self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Unnormalized, + Upcast, Variance, }; use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::debuginfo::debuginfo_locals; @@ -686,7 +687,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let kind = match parent_ty.ty.kind() { &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => { - self.tcx.type_of(def_id).instantiate(self.tcx, args).kind() + self.tcx.type_of(def_id).instantiate(self.tcx, args).skip_norm_wip().kind() } kind => kind, }; @@ -789,7 +790,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { return; }; - ty::EarlyBinder::bind(f_ty.ty).instantiate(self.tcx, args) + ty::EarlyBinder::bind(f_ty.ty) + .instantiate(self.tcx, args) + .skip_norm_wip() } else { let Some(&f_ty) = args.as_coroutine().prefix_tys().get(f.index()) else { @@ -1037,7 +1040,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { assert_eq!(idx, FIRST_VARIANT); let dest_ty = self.tcx.normalize_erasing_regions( self.typing_env, - adt_def.non_enum_variant().fields[field].ty(self.tcx, args), + Unnormalized::new_wip( + adt_def.non_enum_variant().fields[field].ty(self.tcx, args), + ), ); if let [field] = fields.raw.as_slice() { let src_ty = field.ty(self.body, self.tcx); @@ -1060,9 +1065,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { )); } for (src, dest) in std::iter::zip(fields, &variant.fields) { - let dest_ty = self - .tcx - .normalize_erasing_regions(self.typing_env, dest.ty(self.tcx, args)); + let dest_ty = self.tcx.normalize_erasing_regions( + self.typing_env, + Unnormalized::new_wip(dest.ty(self.tcx, args)), + ); if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest_ty) { self.fail(location, "adt field has the wrong type"); } @@ -1399,7 +1405,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self .tcx - .normalize_erasing_regions(self.typing_env, op_ty) + .normalize_erasing_regions( + self.typing_env, + Unnormalized::new_wip(op_ty), + ) .is_sized(self.tcx, self.typing_env) { self.fail( @@ -1409,7 +1418,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } if !self .tcx - .normalize_erasing_regions(self.typing_env, *target_type) + .normalize_erasing_regions( + self.typing_env, + Unnormalized::new_wip(*target_type), + ) .is_sized(self.tcx, self.typing_env) { self.fail( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5c21ff1464c3d..f819ee42441a7 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -227,7 +227,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, - TypeVisitable, TypeVisitableExt, TypeVisitor, VtblEntry, + TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, VtblEntry, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; @@ -1171,10 +1171,14 @@ fn find_tails_for_unsizing<'tcx>( }; let coerce_field = &source_adt_def.non_enum_variant().fields[coerce_index]; // We're getting a possibly unnormalized type, so normalize it. - let source_field = - tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, source_args)); - let target_field = - tcx.normalize_erasing_regions(typing_env, coerce_field.ty(*tcx, target_args)); + let source_field = tcx.normalize_erasing_regions( + typing_env, + Unnormalized::new_wip(coerce_field.ty(*tcx, source_args)), + ); + let target_field = tcx.normalize_erasing_regions( + typing_env, + Unnormalized::new_wip(coerce_field.ty(*tcx, target_args)), + ); find_tails_for_unsizing(tcx, source_field, target_field) } @@ -1533,8 +1537,11 @@ impl<'v> RootCollector<'_, 'v> { return; } - let ty = - self.tcx.type_of(id.owner_id.to_def_id()).instantiate(self.tcx, id_args); + let ty = self + .tcx + .type_of(id.owner_id.to_def_id()) + .instantiate(self.tcx, id_args) + .skip_norm_wip(); assert!(!ty.has_non_region_param()); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } @@ -1599,7 +1606,7 @@ impl<'v> RootCollector<'_, 'v> { DefKind::Closure => { // for 'pub async fn foo(..)' also trying to monomorphize foo::{closure} let is_pub_fn_coroutine = - match *self.tcx.type_of(def_id).instantiate_identity().kind() { + match *self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() { ty::Coroutine(cor_id, _args) => { let tcx = self.tcx; let parent_id = tcx.parent(cor_id); @@ -1616,7 +1623,13 @@ impl<'v> RootCollector<'_, 'v> { .generics_of(self.tcx.typeck_root_def_id_local(def_id)) .requires_monomorphization(self.tcx) { - let instance = match *self.tcx.type_of(def_id).instantiate_identity().kind() { + let instance = match *self + .tcx + .type_of(def_id) + .instantiate_identity() + .skip_norm_wip() + .kind() + { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { @@ -1626,7 +1639,7 @@ impl<'v> RootCollector<'_, 'v> { }; let Ok(instance) = self.tcx.try_normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - instance, + Unnormalized::new_wip(instance), ) else { // Don't ICE on an impossible-to-normalize closure. return; @@ -1704,7 +1717,7 @@ impl<'v> RootCollector<'_, 'v> { // listing. let main_ret_ty = self.tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - main_ret_ty.no_bound_vars().unwrap(), + Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()), ); let start_instance = Instance::expect_resolve( @@ -1750,7 +1763,7 @@ fn create_mono_items_for_default_impls<'tcx>( } }; let impl_args = GenericArgs::for_item(tcx, item.owner_id.to_def_id(), only_region_params); - let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args); + let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args).skip_norm_wip(); // Unlike 'lazy' monomorphization that begins by collecting items transitively // called by `main` or other global items, when eagerly monomorphizing impl @@ -1766,7 +1779,7 @@ fn create_mono_items_for_default_impls<'tcx>( } let typing_env = ty::TypingEnv::fully_monomorphized(); - let trait_ref = tcx.normalize_erasing_regions(typing_env, trait_ref); + let trait_ref = tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(trait_ref)); let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains_key(&method.def_id) { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 2e17885b4f44d..b2a4e90b5bfcb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -12,8 +12,8 @@ use rustc_type_ir::search_graph::CandidateHeadUsages; use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; use rustc_type_ir::{ self as ty, AliasTy, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast, - elaborate, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, + Upcast, elaborate, }; use tracing::{debug, instrument}; @@ -771,6 +771,7 @@ where .cx() .item_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_norm_wip) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -786,6 +787,7 @@ where .cx() .item_non_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_norm_wip) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -1066,6 +1068,7 @@ where .cx() .item_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_norm_wip) { let assumption = item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty }); diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 0543143ef8fea..c3bffb5475c76 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -9,7 +9,7 @@ use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{ self as ty, Binder, FallibleTypeFolder, Interner, Movability, Mutability, TypeFoldable, - TypeSuperFoldable, Upcast as _, elaborate, + TypeSuperFoldable, Unnormalized, Upcast as _, elaborate, }; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; @@ -87,6 +87,7 @@ where .cx() .coroutine_hidden_types(def_id) .instantiate(cx, args) + .skip_norm_wip() .map_bound(|bound| bound.types.to_vec())), ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), @@ -94,15 +95,18 @@ where // For `PhantomData`, we pass `T`. ty::Adt(def, args) if def.is_phantom_data() => Ok(ty::Binder::dummy(vec![args.type_at(0)])), - ty::Adt(def, args) => { - Ok(ty::Binder::dummy(def.all_field_tys(cx).iter_instantiated(cx, args).collect())) - } + ty::Adt(def, args) => Ok(ty::Binder::dummy( + def.all_field_tys(cx) + .iter_instantiated(cx, args) + .map(Unnormalized::skip_norm_wip) + .collect(), + )), ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - Ok(ty::Binder::dummy(vec![cx.type_of(def_id).instantiate(cx, args)])) + Ok(ty::Binder::dummy(vec![cx.type_of(def_id).instantiate(cx, args).skip_norm_wip()])) } } } @@ -178,7 +182,7 @@ where // even if the ADT is {meta,pointee,}sized for all possible args. ty::Adt(def, args) => { if let Some(crit) = def.sizedness_constraint(ecx.cx(), sizedness) { - Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)])) + Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args).skip_norm_wip()])) } else { Ok(ty::Binder::dummy(vec![])) } @@ -264,6 +268,7 @@ where .cx() .coroutine_hidden_types(def_id) .instantiate(ecx.cx(), args) + .skip_norm_wip() .map_bound(|bound| bound.types.to_vec())), } } @@ -281,6 +286,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( { Ok(( sig.instantiate(cx, args) + .skip_norm_wip() .map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())), def_id.into(), args, @@ -759,6 +766,7 @@ pub(in crate::solve) fn const_conditions_for_destruct( let mut const_conditions: Vec<_> = adt_def .all_field_tys(cx) .iter_instantiated(cx, args) + .map(Unnormalized::skip_norm_wip) .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty])) .collect(); match adt_def.destructor(cx) { @@ -884,6 +892,7 @@ where cx, cx.explicit_super_predicates_of(trait_ref.def_id) .iter_instantiated(cx, trait_ref.args) + .map(Unnormalized::skip_norm_wip) .map(|(pred, _)| pred), )); @@ -896,8 +905,11 @@ where continue; } - requirements - .extend(cx.item_bounds(associated_type_def_id).iter_instantiated(cx, trait_ref.args)); + requirements.extend( + cx.item_bounds(associated_type_def_id) + .iter_instantiated(cx, trait_ref.args) + .map(Unnormalized::skip_norm_wip), + ); } let mut replace_projection_with: HashMap<_, Vec<_>> = HashMap::default(); diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 3e44ba689cd25..acbc413537883 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -6,7 +6,7 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind}; -use rustc_type_ir::{self as ty, Interner, TypingMode, elaborate}; +use rustc_type_ir::{self as ty, Interner, TypingMode, Unnormalized, elaborate}; use tracing::instrument; use super::assembly::{Candidate, structural_traits}; @@ -92,6 +92,7 @@ where cx, cx.explicit_implied_const_bounds(alias_ty.kind.def_id()) .iter_instantiated(cx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) .map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)), ) { candidates.extend(Self::probe_and_match_goal_against_assumption( @@ -105,6 +106,7 @@ where GoalSource::AliasBoundConstCondition, cx.const_conditions(alias_ty.kind.def_id()) .iter_instantiated(cx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) .map(|trait_ref| { goal.with( cx, @@ -155,12 +157,13 @@ where ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id.into()); ecx.record_impl_args(impl_args); - let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip(); ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; let where_clause_bounds = cx .predicates_of(impl_def_id.into()) .iter_instantiated(cx, impl_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); @@ -168,6 +171,7 @@ where let const_conditions = cx .const_conditions(impl_def_id.into()) .iter_instantiated(cx, impl_args) + .map(Unnormalized::skip_norm_wip) .map(|bound_trait_ref| { goal.with( cx, @@ -206,11 +210,13 @@ where let where_clause_bounds = cx .predicates_of(goal.predicate.def_id().into()) .iter_instantiated(cx, goal.predicate.trait_ref.args) + .map(Unnormalized::skip_norm_wip) .map(|p| goal.with(cx, p)); let const_conditions = cx .const_conditions(goal.predicate.def_id().into()) .iter_instantiated(cx, goal.predicate.trait_ref.args) + .map(Unnormalized::skip_norm_wip) .map(|bound_trait_ref| { goal.with( cx, @@ -292,6 +298,7 @@ where let requirements = cx .const_conditions(def_id) .iter_instantiated(cx, args) + .map(Unnormalized::skip_norm_wip) .map(|trait_ref| { ( GoalSource::ImplWhereBound, diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 58bd7cf663d98..d37b328920ce1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -218,7 +218,7 @@ where return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } ty::ConstKind::Unevaluated(uv) => { - self.cx().type_of(uv.def.into()).instantiate(self.cx(), uv.args) + self.cx().type_of(uv.def.into()).instantiate(self.cx(), uv.args).skip_norm_wip() } ty::ConstKind::Expr(_) => unimplemented!( "`feature(generic_const_exprs)` is not supported in the new trait solver" diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs index 8777f84957a79..c827494dd2906 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/free_alias.rs @@ -4,7 +4,7 @@ //! Since a free alias is never ambiguous, this just computes the `type_of` of //! the alias and registers the where-clauses of the type alias. -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, Interner, Unnormalized}; use crate::delegate::SolverDelegate; use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult}; @@ -26,13 +26,17 @@ where GoalSource::Misc, cx.predicates_of(free_alias.def_id) .iter_instantiated(cx, free_alias.args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); let actual = if free_alias.kind(cx).is_type() { - cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args).into() + cx.type_of(free_alias.def_id).instantiate(cx, free_alias.args).skip_norm_wip().into() } else { - cx.const_of_item(free_alias.def_id).instantiate(cx, free_alias.args).into() + cx.const_of_item(free_alias.def_id) + .instantiate(cx, free_alias.args) + .skip_norm_wip() + .into() }; self.instantiate_normalizes_to_term(goal, actual); diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs index 42aa237762d9e..7b228d4c7b46e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs @@ -5,7 +5,7 @@ //! 2. equate the self type, and //! 3. instantiate and register where clauses. -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, Interner, Unnormalized}; use crate::delegate::SolverDelegate; use crate::solve::{Certainty, EvalCtxt, Goal, GoalSource, QueryResult}; @@ -29,7 +29,7 @@ where self.eq( goal.param_env, inherent.self_ty(), - cx.type_of(impl_def_id).instantiate(cx, impl_args), + cx.type_of(impl_def_id).instantiate(cx, impl_args).skip_norm_wip(), )?; // Equate IAT with the RHS of the project goal @@ -48,13 +48,14 @@ where GoalSource::Misc, cx.predicates_of(inherent.def_id) .iter_instantiated(cx, inherent_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); let normalized = if inherent.kind(cx).is_type() { - cx.type_of(inherent.def_id).instantiate(cx, inherent_args).into() + cx.type_of(inherent.def_id).instantiate(cx, inherent_args).skip_norm_wip().into() } else { - cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).into() + cx.const_of_item(inherent.def_id).instantiate(cx, inherent_args).skip_norm_wip().into() }; self.instantiate_normalizes_to_term(goal, normalized); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 4deb6ed0bb81f..bbc5739268ef7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -7,7 +7,9 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; use rustc_type_ir::solve::SizedTraitKind; -use rustc_type_ir::{self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Upcast as _}; +use rustc_type_ir::{ + self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _, +}; use tracing::instrument; use crate::delegate::SolverDelegate; @@ -178,6 +180,7 @@ where GoalSource::AliasWellFormed, cx.own_predicates_of(goal.predicate.def_id()) .iter_instantiated(cx, goal.predicate.alias.args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); @@ -235,13 +238,14 @@ where ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id.into()); - let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip(); ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; let where_clause_bounds = cx .predicates_of(impl_def_id.into()) .iter_instantiated(cx, impl_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); @@ -258,6 +262,7 @@ where GoalSource::AliasWellFormed, cx.own_predicates_of(goal.predicate.def_id()) .iter_instantiated(cx, goal.predicate.alias.args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); @@ -388,7 +393,10 @@ where kind => panic!("expected projection, found {kind:?}"), }; - ecx.instantiate_normalizes_to_term(goal, term.instantiate(cx, target_args)); + ecx.instantiate_normalizes_to_term( + goal, + term.instantiate(cx, target_args).skip_norm_wip(), + ); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -651,6 +659,7 @@ where let dyn_metadata = cx.require_lang_item(SolverLangItem::DynMetadata); cx.type_of(dyn_metadata) .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) + .skip_norm_wip() } ty::Alias(_) | ty::Param(_) | ty::Placeholder(..) => { @@ -684,9 +693,11 @@ where ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { None => Ty::new_unit(cx), - Some(tail_ty) => { - Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) - } + Some(tail_ty) => Ty::new_projection( + cx, + metadata_def_id, + [tail_ty.instantiate(cx, args).skip_norm_wip()], + ), }, ty::Adt(_, _) => Ty::new_unit(cx), @@ -1000,7 +1011,8 @@ where let target_args = self.fresh_args_for_item(target_container_def_id); let target_trait_ref = cx .impl_trait_ref(target_container_def_id.try_into().unwrap()) - .instantiate(cx, target_args); + .instantiate(cx, target_args) + .skip_norm_wip(); // Relate source impl to target impl by equating trait refs. self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?; // Also add predicates since they may be needed to constrain the @@ -1009,6 +1021,7 @@ where GoalSource::Misc, cx.predicates_of(target_container_def_id) .iter_instantiated(cx, target_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id.into(), target_args) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs index 9b2bd7cb74ff0..931dd293973a1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs @@ -86,7 +86,8 @@ where TypingMode::Borrowck { .. } => { let actual = cx .type_of_opaque_hir_typeck(def_id) - .instantiate(cx, opaque_ty.args); + .instantiate(cx, opaque_ty.args) + .skip_norm_wip(); let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() { ty::ReErased => self.next_region_var(), _ => re, @@ -117,7 +118,8 @@ where return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); }; - let actual = cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args); + let actual = + cx.type_of(def_id.into()).instantiate(cx, opaque_ty.args).skip_norm_wip(); // FIXME: Actually use a proper binder here instead of relying on `ReErased`. // // This is also probably unsound or sth :shrug: @@ -130,7 +132,8 @@ where } TypingMode::PostAnalysis => { // FIXME: Add an assertion that opaque type storage is empty. - let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args); + let actual = + cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args).skip_norm_wip(); self.eq(goal.param_env, expected, actual)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 33c165fbea6c4..ffe90da4cb0fe 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -9,7 +9,7 @@ use rustc_type_ir::solve::{ }; use rustc_type_ir::{ self as ty, FieldInfo, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef, - TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, + TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _, elaborate, }; use tracing::{debug, instrument, trace}; @@ -96,12 +96,13 @@ where ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { let impl_args = ecx.fresh_args_for_item(impl_def_id.into()); ecx.record_impl_args(impl_args); - let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip(); ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; let where_clause_bounds = cx .predicates_of(impl_def_id.into()) .iter_instantiated(cx, impl_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); @@ -112,6 +113,7 @@ where GoalSource::Misc, cx.impl_super_outlives(impl_def_id) .iter_instantiated(cx, impl_args) + .map(Unnormalized::skip_norm_wip) .map(|pred| goal.with(cx, pred)), ); @@ -270,6 +272,7 @@ where let nested_obligations = cx .predicates_of(goal.predicate.def_id().into()) .iter_instantiated(cx, goal.predicate.trait_ref.args) + .map(Unnormalized::skip_norm_wip) .map(|p| goal.with(cx, p)); // While you could think of trait aliases to have a single builtin impl // which uses its implied trait bounds as where-clauses, using @@ -1181,8 +1184,8 @@ where let tail_field_ty = def.struct_tail_ty(cx).unwrap(); - let a_tail_ty = tail_field_ty.instantiate(cx, a_args); - let b_tail_ty = tail_field_ty.instantiate(cx, b_args); + let a_tail_ty = tail_field_ty.instantiate(cx, a_args).skip_norm_wip(); + let b_tail_ty = tail_field_ty.instantiate(cx, b_args).skip_norm_wip(); // Instantiate just the unsizing params from B into A. The type after // this instantiation must be equal to B. This is so we don't unsize diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 35bfad3a877f2..f8a0cfaecf8e9 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -61,7 +61,7 @@ fn dump_abi_of_fn_item( Ok(Some(instance)) => instance, Ok(None) => { // Not sure what to do here, but `LayoutError::Unknown` seems reasonable? - let ty = tcx.type_of(item_def_id).instantiate_identity(); + let ty = tcx.type_of(item_def_id).instantiate_identity().skip_norm_wip(); tcx.dcx().span_fatal(tcx.def_span(item_def_id), LayoutError::Unknown(ty).to_string()); } Err(_guaranteed) => return, @@ -113,7 +113,7 @@ fn dump_abi_of_fn_type( attr_kind: RustcAbiAttrKind, ) { let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); - let ty = tcx.type_of(item_def_id).instantiate_identity(); + let ty = tcx.type_of(item_def_id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(item_def_id); if !ensure_wf(tcx, typing_env, ty, item_def_id, span) { return; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c7a3ee456f88d..dfd55c83b446b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -33,7 +33,7 @@ use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint; @@ -1660,11 +1660,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let fresh_args = infcx.fresh_args_for_item(span, def_id.to_def_id()); let sig = tcx.liberate_late_bound_regions( def_id.to_def_id(), - tcx.fn_sig(def_id).instantiate(tcx, fresh_args), + tcx.fn_sig(def_id).instantiate(tcx, fresh_args).skip_norm_wip(), ); let mut cause = ObligationCause::misc(span, def_id); - let sig = ocx.normalize(&cause, param_env, sig); + let sig = ocx.normalize(&cause, param_env, Unnormalized::new_wip(sig)); // proc macro is not WF. let errors = ocx.try_evaluate_obligations(); diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index 7f80de9da41f4..1bb4147900f1b 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -12,7 +12,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibility, Level}; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility, + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Unnormalized, Visibility, }; use rustc_session::config::CrateType; use rustc_span::Span; @@ -211,7 +211,10 @@ impl<'tcx, 'a> ExportableItemsChecker<'tcx, 'a> { let sig = self .tcx - .try_normalize_erasing_regions(ty::TypingEnv::non_body_analysis(self.tcx, def_id), sig) + .try_normalize_erasing_regions( + ty::TypingEnv::non_body_analysis(self.tcx, def_id), + Unnormalized::new_wip(sig), + ) .unwrap_or(sig); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); @@ -280,7 +283,8 @@ impl<'tcx, 'a> TypeVisitor> for ExportableItemsChecker<'tcx, 'a> { } for variant in adt_def.variants() { for field in &variant.fields { - let field_ty = self.tcx.type_of(field.did).instantiate_identity(); + let field_ty = + self.tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); field_ty.visit_with(self)?; } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d5ef9ee9335c5..0423613069faf 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -382,7 +382,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind && let impl_of = self.tcx.local_parent(impl_item.owner_id.def_id) && self.tcx.is_automatically_derived(impl_of.to_def_id()) - && let trait_ref = self.tcx.impl_trait_ref(impl_of).instantiate_identity() + && let trait_ref = + self.tcx.impl_trait_ref(impl_of).instantiate_identity().skip_norm_wip() && find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads) { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() @@ -448,7 +449,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { //// This is done to handle the case where, for example, the static //// method of a private type is used, but the type itself is never //// called directly. - let self_ty = self.tcx.type_of(item).instantiate_identity(); + let self_ty = self.tcx.type_of(item).instantiate_identity().skip_norm_wip(); match *self_ty.kind() { ty::Adt(def, _) => self.check_def_id(def.did()), ty::Foreign(did) => self.check_def_id(did), @@ -507,7 +508,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } // The impl or impl item is used if the corresponding trait or trait item is used and the ty is used. - if let ty::Adt(adt, _) = self.tcx.type_of(impl_block_id).instantiate_identity().kind() + if let ty::Adt(adt, _) = + self.tcx.type_of(impl_block_id).instantiate_identity().skip_norm_wip().kind() && let Some(adt_def_id) = adt.did().as_local() && !self.live_symbols.contains(&adt_def_id) { @@ -927,7 +929,7 @@ impl<'tcx> DeadVisitor<'tcx> { if self.live_symbols.contains(&field.did.expect_local()) { return ShouldWarnAboutField::No; } - let field_type = self.tcx.type_of(field.did).instantiate_identity(); + let field_type = self.tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); if field_type.is_phantom_data() { return ShouldWarnAboutField::No; } @@ -1077,7 +1079,7 @@ impl<'tcx> DeadVisitor<'tcx> { && let impl_did = tcx.local_parent(dead_item.def_id) && let DefKind::Impl { of_trait: false } = tcx.def_kind(impl_did) && let ty::Adt(maybe_enum, _) = - tcx.type_of(impl_did).instantiate_identity().kind() + tcx.type_of(impl_did).instantiate_identity().skip_norm_wip().kind() && maybe_enum.is_enum() && let Some(variant) = maybe_enum.variants().iter().find(|i| i.name == dead_item.name) diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 3317a8d03f6da..19f2ca3af9232 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::find_attr; use rustc_middle::span_bug; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_span::Span; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::TyCtxtInferExt; @@ -61,7 +61,7 @@ pub fn ensure_wf<'tcx>( fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, kinds: &[RustcDumpLayoutKind]) { let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id); - let ty = tcx.type_of(item_def_id).instantiate_identity(); + let ty = tcx.type_of(item_def_id).instantiate_identity().skip_norm_wip(); let span = tcx.def_span(item_def_id.to_def_id()); if !ensure_wf(tcx, typing_env, ty, item_def_id, span) { return; @@ -75,7 +75,8 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, kinds: &[RustcDumpLa format!("backend_repr: {:?}", ty_layout.backend_repr) } RustcDumpLayoutKind::Debug => { - let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty); + let normalized_ty = + tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)); // FIXME: using the `Debug` impl here isn't ideal. format!("layout_of({normalized_ty}) = {:#?}", *ty_layout) } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index b0f589955124d..a8f68108bd76d 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -11,7 +11,8 @@ use rustc_middle::middle::stability::EvalResult; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ - self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, + self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Unnormalized, + VariantDef, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -151,7 +152,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { self.typeck_results .hidden_types .get(&key.def_id) - .map(|x| x.ty.instantiate(self.tcx, key.args)) + .map(|x| x.ty.instantiate(self.tcx, key.args).skip_norm_wip()) } // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { @@ -195,7 +196,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. let ty = - self.tcx.try_normalize_erasing_regions(self.typing_env, ty).unwrap_or_else(|e| { + self.tcx.try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(ty)).unwrap_or_else(|e| { self.tcx.dcx().span_delayed_bug( self.scrut_span, format!( diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 2147a160d3d6e..58121b8123c35 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -197,7 +197,9 @@ where // `my_func` is public, so we need to visit signatures. if let ty::FnDef(..) = ty_kind { // FIXME: this should probably use `args` from `FnDef` - try_visit!(tcx.fn_sig(def_id).instantiate_identity().visit_with(self)); + try_visit!( + tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().visit_with(self) + ); } // Inherent static methods don't have self type in args. // Something like `fn() {my_method}` type of the method @@ -206,7 +208,12 @@ where if let Some(assoc_item) = tcx.opt_associated_item(def_id) && let Some(impl_def_id) = assoc_item.impl_container(tcx) { - try_visit!(tcx.type_of(impl_def_id).instantiate_identity().visit_with(self)); + try_visit!( + tcx.type_of(impl_def_id) + .instantiate_identity() + .skip_norm_wip() + .visit_with(self) + ); } } ty::Alias( @@ -373,9 +380,9 @@ trait VisibilityLike: Sized { effective_visibilities: &EffectiveVisibilities, ) -> Self { let mut find = FindMin::<_, SHALLOW> { tcx, effective_visibilities, min: Self::MAX }; - find.visit(tcx.type_of(def_id).instantiate_identity()); + find.visit(tcx.type_of(def_id).instantiate_identity().skip_norm_wip()); if of_trait { - find.visit_trait(tcx.impl_trait_ref(def_id).instantiate_identity()); + find.visit_trait(tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip()); } find.min } @@ -832,10 +839,12 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { fn generics(&mut self) -> &mut Self { for param in &self.ev.tcx.generics_of(self.item_def_id).own_params { if let GenericParamDefKind::Const { .. } = param.kind { - self.visit(self.ev.tcx.type_of(param.def_id).instantiate_identity()); + self.visit( + self.ev.tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip(), + ); } if let Some(default) = param.default_value(self.ev.tcx) { - self.visit(default.instantiate_identity()); + self.visit(default.instantiate_identity().skip_norm_wip()); } } self @@ -852,12 +861,14 @@ impl ReachEverythingInTheInterfaceVisitor<'_, '_> { } fn ty(&mut self) -> &mut Self { - self.visit(self.ev.tcx.type_of(self.item_def_id).instantiate_identity()); + self.visit(self.ev.tcx.type_of(self.item_def_id).instantiate_identity().skip_norm_wip()); self } fn trait_ref(&mut self) -> &mut Self { - self.visit_trait(self.ev.tcx.impl_trait_ref(self.item_def_id).instantiate_identity()); + self.visit_trait( + self.ev.tcx.impl_trait_ref(self.item_def_id).instantiate_identity().skip_norm_wip(), + ); self } } @@ -1260,7 +1271,10 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { .maybe_typeck_results .unwrap_or_else(|| span_bug!(self.span, "`hir::Expr` outside of a body")); if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) { - if self.visit(self.tcx.type_of(def_id).instantiate_identity()).is_break() { + if self + .visit(self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()) + .is_break() + { return; } } else { @@ -1389,10 +1403,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { self.in_primary_interface = true; for param in &self.tcx.generics_of(self.item_def_id).own_params { if let GenericParamDefKind::Const { .. } = param.kind { - let _ = self.visit(self.tcx.type_of(param.def_id).instantiate_identity()); + let _ = self + .visit(self.tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip()); } if let Some(default) = param.default_value(self.tcx) { - let _ = self.visit(default.instantiate_identity()); + let _ = self.visit(default.instantiate_identity().skip_norm_wip()); } } self @@ -1418,13 +1433,16 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn ty(&mut self) -> &mut Self { self.in_primary_interface = true; - let _ = self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity()); + let _ = + self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity().skip_norm_wip()); self } fn trait_ref(&mut self) -> &mut Self { self.in_primary_interface = true; - let _ = self.visit_trait(self.tcx.impl_trait_ref(self.item_def_id).instantiate_identity()); + let _ = self.visit_trait( + self.tcx.impl_trait_ref(self.item_def_id).instantiate_identity().skip_norm_wip(), + ); self } @@ -1782,7 +1800,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) { let trait_ref = tcx.impl_trait_ref(def_id); - let trait_ref = trait_ref.instantiate_identity(); + let trait_ref = trait_ref.instantiate_identity().skip_norm_wip(); visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().trait_ref.path.span; let _ = diff --git a/compiler/rustc_public_bridge/src/context/impls.rs b/compiler/rustc_public_bridge/src/context/impls.rs index 359769d4cfe4c..1df2b1fa64285 100644 --- a/compiler/rustc_public_bridge/src/context/impls.rs +++ b/compiler/rustc_public_bridge/src/context/impls.rs @@ -379,7 +379,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { def_id: DefId, args_ref: GenericArgsRef<'tcx>, ) -> Binder<'tcx, FnSig<'tcx>> { - let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref); + let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref).skip_norm_wip(); sig } @@ -541,7 +541,7 @@ impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> { /// Returns the type of given crate item. pub fn def_ty(&self, item: DefId) -> Ty<'tcx> { - self.tcx.type_of(item).instantiate_identity() + self.tcx.type_of(item).instantiate_identity().skip_norm_wip() } /// Returns the type of given definition instantiated with the given arguments. diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 26979c24bdb68..86006edcede98 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -88,8 +88,10 @@ fn encode_args<'tcx>( } GenericArgKind::Const(c) => { let n = n + (has_erased_self as usize); - let ct_ty = - tcx.type_of(def_generics.param_at(n, tcx).def_id).instantiate_identity(); + let ct_ty = tcx + .type_of(def_generics.param_at(n, tcx).def_id) + .instantiate_identity() + .skip_norm_wip(); s.push_str(&encode_const(tcx, c, ct_ty, dict, options)); } } @@ -250,7 +252,9 @@ fn encode_predicate<'tcx>( TermKind::Const(c) => s.push_str(&encode_const( tcx, c, - tcx.type_of(projection.def_id).instantiate(tcx, projection.args), + tcx.type_of(projection.def_id) + .instantiate(tcx, projection.args) + .skip_norm_wip(), dict, options, )), diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 5691ed1469276..6a36d6b3e1f65 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -11,6 +11,7 @@ use rustc_middle::bug; use rustc_middle::ty::{ self, AssocContainer, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UintTy, + Unnormalized, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; @@ -143,7 +144,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { let variant = adt_def.non_enum_variant(); let typing_env = ty::TypingEnv::post_analysis(self.tcx, variant.def_id); let field = variant.fields.iter().find(|field| { - let ty = self.tcx.type_of(field.did).instantiate_identity(); + let ty = self.tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); let is_zst = self .tcx .layout_of(typing_env.as_query_input(ty)) @@ -153,7 +154,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { if let Some(field) = field { let ty0 = self.tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - field.ty(self.tcx, args), + Unnormalized::new_wip(field.ty(self.tcx, args)), ); // Generalize any repr(transparent) user-defined type that is either a // pointer or reference, and either references itself or any other type that @@ -214,9 +215,10 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } } - ty::Alias(..) => self.fold_ty( - self.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t), - ), + ty::Alias(..) => self.fold_ty(self.tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(t), + )), ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => { bug!("fold_ty: unexpected `{:?}`", t.kind()); @@ -250,7 +252,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc ); let term = tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - projection_term.to_term(tcx), + Unnormalized::new_wip(projection_term.to_term(tcx)), ); debug!("Projection {:?} -> {term}", projection_term.to_term(tcx),); ty::ExistentialPredicate::Projection( diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 89ee4743a6f43..597a032086a83 100644 --- a/compiler/rustc_symbol_mangling/src/export.rs +++ b/compiler/rustc_symbol_mangling/src/export.rs @@ -91,7 +91,8 @@ impl<'tcx> AbiHashStable<'tcx> for Ty<'tcx> { variant.name.abi_hash(tcx, hasher); for field in &variant.fields { field.name.abi_hash(tcx, hasher); - let field_ty = tcx.type_of(field.did).instantiate_identity(); + let field_ty = + tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); field_ty.abi_hash(tcx, hasher); } } @@ -161,7 +162,7 @@ pub(crate) fn compute_hash_of_export_fn<'tcx>( debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn); let args = instance.args; - let sig_ty = tcx.fn_sig(def_id).instantiate(tcx, args); + let sig_ty = tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(); let sig_ty = tcx.instantiate_bound_regions_with_erased(sig_ty); let hash = { diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index e078537533d5c..b574ca2186a9f 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -9,6 +9,7 @@ use rustc_middle::bug; use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer}; use rustc_middle::ty::{ self, GenericArg, GenericArgKind, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt, + Unnormalized, }; use tracing::debug; @@ -32,7 +33,7 @@ pub(super) fn mangle<'tcx>( | DefPathData::ValueNs(_) | DefPathData::Closure | DefPathData::SyntheticCoroutineBody => { - instance_ty = tcx.type_of(ty_def_id).instantiate_identity(); + instance_ty = tcx.type_of(ty_def_id).instantiate_identity().skip_norm_wip(); debug!(?instance_ty); break; } @@ -434,8 +435,9 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> { { ( ty::TypingEnv::post_analysis(self.tcx, impl_def_id), - self_ty.instantiate_identity(), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()), + self_ty.instantiate_identity().skip_norm_wip(), + impl_trait_ref + .map(|impl_trait_ref| impl_trait_ref.instantiate_identity().skip_norm_wip()), ) } else { assert!( @@ -445,19 +447,24 @@ impl<'tcx> Printer<'tcx> for LegacySymbolMangler<'tcx> { ); ( ty::TypingEnv::fully_monomorphized(), - self_ty.instantiate(self.tcx, args), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)), + self_ty.instantiate(self.tcx, args).skip_norm_wip(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate(self.tcx, args).skip_norm_wip() + }), ) }; match &mut impl_trait_ref { Some(impl_trait_ref) => { assert_eq!(impl_trait_ref.self_ty(), self_ty); - *impl_trait_ref = self.tcx.normalize_erasing_regions(typing_env, *impl_trait_ref); + *impl_trait_ref = self + .tcx + .normalize_erasing_regions(typing_env, Unnormalized::new_wip(*impl_trait_ref)); self_ty = impl_trait_ref.self_ty(); } None => { - self_ty = self.tcx.normalize_erasing_regions(typing_env, self_ty); + self_ty = + self.tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(self_ty)); } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index fa839eb845586..99f9cddc08fff 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, PrintError, Printer}; use rustc_middle::ty::{ self, FloatTy, GenericArg, GenericArgKind, Instance, IntTy, ReifyReason, Ty, TyCtxt, - TypeVisitable, TypeVisitableExt, UintTy, + TypeVisitable, TypeVisitableExt, UintTy, Unnormalized, }; use rustc_span::sym; @@ -30,7 +30,10 @@ pub(super) fn mangle<'tcx>( ) -> String { let def_id = instance.def_id(); // FIXME(eddyb) this should ideally not be needed. - let args = tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), instance.args); + let args = tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(instance.args), + ); let prefix = "_R"; let mut p: V0SymbolMangler<'_> = V0SymbolMangler { @@ -341,8 +344,9 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { { ( ty::TypingEnv::post_analysis(self.tcx, impl_def_id), - self_ty.instantiate_identity(), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()), + self_ty.instantiate_identity().skip_norm_wip(), + impl_trait_ref + .map(|impl_trait_ref| impl_trait_ref.instantiate_identity().skip_norm_wip()), ) } else { assert!( @@ -352,19 +356,24 @@ impl<'tcx> Printer<'tcx> for V0SymbolMangler<'tcx> { ); ( ty::TypingEnv::fully_monomorphized(), - self_ty.instantiate(self.tcx, args), - impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(self.tcx, args)), + self_ty.instantiate(self.tcx, args).skip_norm_wip(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate(self.tcx, args).skip_norm_wip() + }), ) }; match &mut impl_trait_ref { Some(impl_trait_ref) => { assert_eq!(impl_trait_ref.self_ty(), self_ty); - *impl_trait_ref = self.tcx.normalize_erasing_regions(typing_env, *impl_trait_ref); + *impl_trait_ref = self + .tcx + .normalize_erasing_regions(typing_env, Unnormalized::new_wip(*impl_trait_ref)); self_ty = impl_trait_ref.self_ty(); } None => { - self_ty = self.tcx.normalize_erasing_regions(typing_env, self_ty); + self_ty = + self.tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(self_ty)); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 19a6c5dfe5ee6..40242885e1026 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -65,7 +65,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt}; use rustc_middle::ty::print::{PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths}; use rustc_middle::ty::{ self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, + TypeVisitableExt, Unnormalized, }; use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym}; use tracing::{debug, instrument}; @@ -196,6 +196,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx .explicit_item_self_bounds(def_id) .iter_instantiated_copied(self.tcx, args) + .map(Unnormalized::skip_norm_wip) .find_map(|(predicate, _)| { predicate .kind() @@ -277,7 +278,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_shadowed = self.infcx.probe(|_| { let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs).skip_norm_wip(); let expected_trait_ref = alias.trait_ref(tcx); @@ -307,7 +309,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if !tcx.check_args_compatible(impl_item_def_id, rebased_args) { return false; } - let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args); + let impl_assoc_ty = + tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args).skip_norm_wip(); self.infcx.can_eq(param_env, impl_assoc_ty, concrete) }); @@ -1272,8 +1275,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => { - let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1); - let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2); + let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1).skip_norm_wip(); + let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2).skip_norm_wip(); self.cmp_fn_sig( &sig1, Some((*did1, Some(args1))), @@ -1283,12 +1286,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } (ty::FnDef(did1, args1), ty::FnPtr(sig_tys2, hdr2)) => { - let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1); + let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1).skip_norm_wip(); self.cmp_fn_sig(&sig1, Some((*did1, Some(args1))), &sig_tys2.with(*hdr2), None) } (ty::FnPtr(sig_tys1, hdr1), ty::FnDef(did2, args2)) => { - let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2); + let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2).skip_norm_wip(); self.cmp_fn_sig(&sig_tys1.with(*hdr1), None, &sig2, Some((*did2, Some(args2)))) } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 86b6a3c7b7663..acc8fae24a6d0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -1202,7 +1202,8 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let parent_def_id = generics.parent.unwrap(); if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) { - let parent_ty = tcx.type_of(parent_def_id).instantiate(tcx, args); + let parent_ty = + tcx.type_of(parent_def_id).instantiate(tcx, args).skip_norm_wip(); match (parent_ty.kind(), &ty.kind) { ( ty::Adt(def, args), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs index 0904177ea8bb1..711aab43d9e7b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; // Next, let's figure out the set of trait objects with implicit static bounds - let ty = self.tcx().type_of(*impl_def_id).instantiate_identity(); + let ty = self.tcx().type_of(*impl_def_id).instantiate_identity().skip_norm_wip(); let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(ty); let mut traits = vec![]; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 5f2aab38c31c8..f7a794a033349 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -66,7 +66,7 @@ pub fn find_param_with_region<'tcx>( let owner_id = tcx.hir_body_owner(body.id()); let fn_decl = tcx.hir_fn_decl_by_hir_id(owner_id)?; - let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); + let poly_fn_sig = tcx.fn_sig(id).instantiate_identity().skip_norm_wip(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); body.params @@ -117,7 +117,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { region_def_id: DefId, hir_sig: &hir::FnSig<'_>, ) -> Option { - let fn_ty = self.tcx().type_of(scope_def_id).instantiate_identity(); + let fn_ty = self.tcx().type_of(scope_def_id).instantiate_identity().skip_norm_wip(); if let ty::FnDef(_, _) = fn_ty.kind() { let ret_ty = fn_ty.fn_sig(self.tcx()).output(); let span = hir_sig.decl.output.span(); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index fb1d25999116d..346f40885fb9b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -842,7 +842,7 @@ fn foo(&self) -> Self::T { String::new() } && !tcx.is_doc_hidden(item.def_id) }) .filter_map(|item| { - let method = tcx.fn_sig(item.def_id).instantiate_identity(); + let method = tcx.fn_sig(item.def_id).instantiate_identity().skip_norm_wip(); match *method.output().skip_binder().kind() { ty::Alias(ty::AliasTy { kind: ty::Projection { def_id: item_def_id }, .. @@ -906,7 +906,7 @@ fn foo(&self) -> Self::T { String::new() } // FIXME: account for returning some type in a trait fn impl that has // an assoc type as a return type (#72076). && let hir::Defaultness::Default { has_value: true } = assoc_item.defaultness(tcx) - && let assoc_ty = tcx.type_of(assoc_item.def_id).instantiate_identity() + && let assoc_ty = tcx.type_of(assoc_item.def_id).instantiate_identity().skip_norm_wip() && self.infcx.can_eq(param_env, assoc_ty, found) { let msg = match assoc_item.container { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 2d5e8190a9b3b..01b7b734c80e2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -440,8 +440,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let ty::Dynamic(preds, _) = ty.kind() && let Some(def_id) = preds.principal_def_id() { - for (clause, span) in - self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) + for (clause, span) in self + .tcx + .predicates_of(def_id) + .instantiate_identity(self.tcx) + .into_iter() + .map(|(c, s)| (c.skip_norm_wip(), s)) { if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) = clause.kind().skip_binder() @@ -584,24 +588,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let trait_ref = self.tcx.impl_trait_ref(impl_def_id); let trait_args = trait_ref .instantiate_identity() + .skip_norm_wip() // Replace the explicit self type with `Self` for better suggestion rendering .with_replaced_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper)) .args; let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id) .rebase_onto(self.tcx, impl_def_id, trait_args); - let Ok(trait_predicates) = - self.tcx - .explicit_predicates_of(trait_item_def_id) - .instantiate_own(self.tcx, trait_item_args) - .map(|(pred, _)| { - if pred.is_suggestable(self.tcx, false) { - Ok(pred.to_string()) - } else { - Err(()) - } - }) - .collect::, ()>>() + let Ok(trait_predicates) = self + .tcx + .explicit_predicates_of(trait_item_def_id) + .instantiate_own(self.tcx, trait_item_args) + .map(|(pred, _)| { + let pred = pred.skip_norm_wip(); + if pred.is_suggestable(self.tcx, false) { Ok(pred.to_string()) } else { Err(()) } + }) + .collect::, ()>>() else { return; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index eed7f0a0bab92..6cd770711cdb3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -411,8 +411,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => { let sig = sig_tys.with(*hdr); let expected_sig = &(self.normalize_fn_sig)(sig); - let found_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args)); + let found_sig = &(self.normalize_fn_sig)( + self.tcx.fn_sig(*did).instantiate(self.tcx, args).skip_norm_wip(), + ); let fn_name = self.tcx.def_path_str_with_args(*did, args); @@ -447,10 +448,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.subdiagnostic(sugg); } (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => { - let expected_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did1).instantiate(self.tcx, args1)); - let found_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2)); + let expected_sig = &(self.normalize_fn_sig)( + self.tcx.fn_sig(*did1).instantiate(self.tcx, args1).skip_norm_wip(), + ); + let found_sig = &(self.normalize_fn_sig)( + self.tcx.fn_sig(*did2).instantiate(self.tcx, args2).skip_norm_wip(), + ); if self.same_type_modulo_infer(*expected_sig, *found_sig) { diag.subdiagnostic(FnUniqTypes); @@ -490,8 +493,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.subdiagnostic(sug); } (ty::FnDef(did, args), ty::FnPtr(sig_tys, hdr)) => { - let expected_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args)); + let expected_sig = &(self.normalize_fn_sig)( + self.tcx.fn_sig(*did).instantiate(self.tcx, args).skip_norm_wip(), + ); let found_sig = &(self.normalize_fn_sig)(sig_tys.with(*hdr)); if !self.same_type_modulo_infer(*found_sig, *expected_sig) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 7f5ed9ecb6d11..78c8c824f30fd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -12,7 +12,7 @@ use rustc_infer::traits::{ Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation, }; use rustc_middle::ty::print::PrintPolyTraitPredicateExt; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _, Unnormalized}; use rustc_session::parse::feature_err_unstable_feature_bound; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span}; use tracing::{debug, instrument}; @@ -44,13 +44,17 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( let obligation_trait_ref = ocx.normalize( &ObligationCause::dummy(), param_env, - placeholder_obligation.trait_ref, + Unnormalized::new_wip(placeholder_obligation.trait_ref), ); let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args); let impl_trait_ref = - ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref); + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(); + let impl_trait_ref = ocx.normalize( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip(impl_trait_ref), + ); if let Err(_) = ocx.eq(&ObligationCause::dummy(), param_env, obligation_trait_ref, impl_trait_ref) @@ -72,7 +76,12 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( .instantiate(tcx, impl_args) .into_iter() .map(|(predicate, _)| { - Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) + Obligation::new( + tcx, + ObligationCause::dummy(), + param_env, + predicate.skip_norm_wip(), + ) }) // Kinda hacky, but let's just throw away obligations that overflow. // This may reduce the accuracy of this check (if the obligation guides @@ -93,7 +102,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( let obligation_trait_ref = ocx.normalize( &ObligationCause::dummy(), param_env, - placeholder_obligation.trait_ref, + Unnormalized::new_wip(placeholder_obligation.trait_ref), ); let param_env_predicate = infcx.instantiate_binder_with_fresh_vars( @@ -101,8 +110,11 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( BoundRegionConversionTime::HigherRankedType, poly_trait_predicate, ); - let param_env_trait_ref = - ocx.normalize(&ObligationCause::dummy(), param_env, param_env_predicate.trait_ref); + let param_env_trait_ref = ocx.normalize( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip(param_env_predicate.trait_ref), + ); if let Err(_) = ocx.eq( &ObligationCause::dummy(), @@ -137,7 +149,9 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( let body_id = obligation.cause.body_id; if body_id != CRATE_DEF_ID { let predicates = tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx); - for (pred, span) in elaborate(tcx, predicates.into_iter()) { + for (pred, span) in + elaborate(tcx, predicates.into_iter().map(|(c, s)| (c.skip_norm_wip(), s))) + { let kind = pred.kind(); if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() && param_env_candidate_may_apply(kind.rebind(trait_pred)) @@ -443,7 +457,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { implementation", vec![format!( "{}", - self.tcx.type_of(impl_def_id).instantiate_identity() + self.tcx + .type_of(impl_def_id) + .instantiate_identity() + .skip_norm_wip() )], ) } else if non_blanket_impl_count < 20 { @@ -457,7 +474,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .map(|&id| { format!( "{}", - self.tcx.type_of(id).instantiate_identity() + self.tcx + .type_of(id) + .instantiate_identity() + .skip_norm_wip() ) }) .collect::>(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index 2c18ffc105503..b1224f3a9c9af 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -5,7 +5,9 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, lang_items}; -use rustc_middle::ty::{AssocContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{ + AssocContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv, Unnormalized, +}; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym}; use tracing::debug; @@ -102,7 +104,7 @@ pub fn call_kind<'tcx>( tcx.get_diagnostic_item(sym::deref_target).expect("deref method but no deref target"); let deref_target_ty = tcx.normalize_erasing_regions( typing_env, - Ty::new_projection(tcx, deref_target_def_id, method_args), + Unnormalized::new_wip(Ty::new_projection(tcx, deref_target_def_id, method_args)), ); let deref_target_span = if let Ok(Some(instance)) = Instance::try_resolve(tcx, typing_env, method_did, method_args) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 04c9edc25d172..42a41991ddff1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -31,7 +31,7 @@ use rustc_middle::ty::print::{ }; use rustc_middle::ty::{ self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, Upcast, + TypeVisitableExt, Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::CrateNum; @@ -1538,7 +1538,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // FIXME(-Znext-solver): For diagnostic purposes, it would be nice // to deeply normalize this type. let normalized_term = - ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term); + ocx.normalize(&obligation.cause, obligation.param_env, Unnormalized::new_wip(unnormalized_term)); // constrain inference variables a bit more to nested obligations from normalize so // we can have more helpful errors. @@ -1570,7 +1570,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Ok(normalized_term) = ocx.structurally_normalize_term( &ObligationCause::dummy(), obligation.param_env, - alias_term.to_term(self.tcx), + Unnormalized::new_wip(alias_term.to_term(self.tcx)), ) else { return None; }; @@ -1987,7 +1987,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .filter_map(|(header, def_id)| { (header.polarity == ty::ImplPolarity::Positive || self.tcx.is_automatically_derived(def_id)) - .then(|| (header.trait_ref.instantiate_identity(), def_id)) + .then(|| (header.trait_ref.instantiate_identity().skip_norm_wip(), def_id)) }) .filter(|(trait_ref, _)| { let self_ty = trait_ref.self_ty(); @@ -2056,7 +2056,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx, ObligationCause::dummy(), param_env, - clause, + clause.skip_norm_wip(), ) }), ); @@ -2393,7 +2393,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .tcx .try_normalize_erasing_regions( ty::TypingEnv::non_body_analysis(self.tcx, cand.impl_def_id), - cand.trait_ref, + Unnormalized::new_wip(cand.trait_ref), ) .unwrap_or(cand.trait_ref); cand @@ -2714,8 +2714,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); - let InferOk { value: cleaned_pred, .. } = - self.infcx.at(&ObligationCause::dummy(), param_env).normalize(cleaned_pred); + let InferOk { value: cleaned_pred, .. } = self + .infcx + .at(&ObligationCause::dummy(), param_env) + .normalize(Unnormalized::new_wip(cleaned_pred)); let obligation = Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred); @@ -2818,7 +2820,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Ok(assume) = ocx.structurally_normalize_const( &obligation.cause, obligation.param_env, - trait_ref.args.const_at(2), + Unnormalized::new_wip(trait_ref.args.const_at(2)), ) else { return (obligation.clone(), trait_predicate); }; @@ -2871,7 +2873,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Ok(assume) = ocx.structurally_normalize_const( &obligation.cause, obligation.param_env, - trait_pred.trait_ref.args.const_at(2), + Unnormalized::new_wip(trait_pred.trait_ref.args.const_at(2)), ) else { self.dcx().span_delayed_bug( span, @@ -3664,7 +3666,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.dcx().struct_span_err(span, "unconstrained generic constant"); let const_span = self.tcx.def_span(uv.def); - let const_ty = self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args); + let const_ty = + self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args).skip_norm_wip(); let cast = if const_ty != self.tcx.types.usize { " as usize" } else { "" }; let msg = "try adding a `where` bound"; match self.tcx.sess.source_map().span_to_snippet(const_span) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 0b80666457e44..67bd3dc63afb1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -455,7 +455,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { use std::fmt::Write; - let trait_ref = tcx.impl_opt_trait_ref(impl_def_id)?.instantiate_identity(); + let trait_ref = tcx.impl_opt_trait_ref(impl_def_id)?.instantiate_identity().skip_norm_wip(); let mut w = "impl".to_owned(); #[derive(Debug, Default)] @@ -485,7 +485,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti " {}{} for {}", tcx.impl_polarity(impl_def_id).as_str(), trait_ref.print_only_trait_path(), - tcx.type_of(impl_def_id).instantiate_identity() + tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip() ) .unwrap(); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index ba7c8d8f1dac1..b6ea4ddc63248 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -98,7 +98,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(def) = self_ty.ty_adt_def() { // We also want to be able to select self's original // signature with no type arguments resolved - self_types.push(self.tcx.type_of(def.did()).instantiate_identity().to_string()); + self_types.push( + self.tcx.type_of(def.did()).instantiate_identity().skip_norm_wip().to_string(), + ); } for GenericParamDef { name, kind, index, .. } in generics.own_params.iter() { @@ -117,7 +119,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // original signature with no type arguments resolved generic_args.push(( *name, - self.tcx.type_of(def.did()).instantiate_identity().to_string(), + self.tcx + .type_of(def.did()) + .instantiate_identity() + .skip_norm_wip() + .to_string(), )); } } @@ -160,8 +166,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(def) = aty.ty_adt_def() { // We also want to be able to select the slice's type's original // signature with no type arguments resolved - self_types - .push(format!("[{}]", self.tcx.type_of(def.did()).instantiate_identity())); + self_types.push(format!( + "[{}]", + self.tcx.type_of(def.did()).instantiate_identity().skip_norm_wip() + )); } if aty.is_integral() { self_types.push("[{integral}]".to_string()); @@ -179,7 +187,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(def) = aty.ty_adt_def() { // We also want to be able to select the array's type's original // signature with no type arguments resolved - let def_ty = self.tcx.type_of(def.did()).instantiate_identity(); + let def_ty = self.tcx.type_of(def.did()).instantiate_identity().skip_norm_wip(); self_types.push(format!("[{def_ty}; _]")); if let Some(n) = len { self_types.push(format!("[{def_ty}; {n}]")); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 9a9238f5c7994..3f4235b4d4768 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -34,8 +34,8 @@ use rustc_middle::ty::print::{ }; use rustc_middle::ty::{ self, AdtKind, GenericArgs, InferTy, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, TypeckResults, Upcast, - suggest_arbitrary_trait_bound, suggest_constraining_type_param, + TypeSuperFoldable, TypeSuperVisitable, TypeVisitableExt, TypeVisitor, TypeckResults, + Unnormalized, Upcast, suggest_arbitrary_trait_bound, suggest_constraining_type_param, }; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; @@ -1427,8 +1427,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) } ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => { - self.tcx.item_self_bounds(def_id).instantiate(self.tcx, args).iter().find_map( - |pred| { + self.tcx + .item_self_bounds(def_id) + .instantiate(self.tcx, args) + .skip_norm_wip() + .iter() + .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() && self .tcx @@ -1444,8 +1448,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { None } - }, - ) + }) } ty::Dynamic(data, _) => data.iter().find_map(|pred| { if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder() @@ -1519,7 +1522,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // implied by wf, but also because that would possibly result in // erroneous errors later on. let InferOk { value: output, obligations: _ } = - self.at(&ObligationCause::dummy(), param_env).normalize(output); + self.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(output)); if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) } } @@ -2567,7 +2570,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // that the predicate that we failed to satisfy is a `Fn`-like trait. if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) - && let Some(pred) = predicates.predicates.get(idx) + && let Some(pred) = predicates.predicates.get(idx).map(|p| p.as_ref().skip_norm_wip()) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() && self.tcx.is_fn_trait(trait_pred.def_id()) { @@ -2579,6 +2582,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Find another predicate whose self-type is equal to the expected self type, // but whose args don't match. let other_pred = predicates.into_iter().enumerate().find(|&(other_idx, (pred, _))| { + let pred = pred.skip_norm_wip(); match pred.kind().skip_binder() { ty::ClauseKind::Trait(trait_pred) if self.tcx.is_fn_trait(trait_pred.def_id()) @@ -3362,7 +3366,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .map(|&&t| { with_no_trimmed_paths!(format!( " {}", - tcx.type_of(t).instantiate_identity(), + tcx.type_of(t) + .instantiate_identity() + .skip_norm_wip(), )) }) .collect::>(); @@ -4251,8 +4257,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { [trait_pred.self_ty()], ) }); - let InferOk { value: projection_ty, .. } = - self.at(&obligation.cause, obligation.param_env).normalize(projection_ty); + let InferOk { value: projection_ty, .. } = self + .at(&obligation.cause, obligation.param_env) + .normalize(Unnormalized::new_wip(projection_ty)); debug!( normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty) @@ -4552,6 +4559,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) && let Some(where_pred) = where_clauses.predicates.get(idx) { + let where_pred = where_pred.as_ref().skip_norm_wip(); if let Some(where_pred) = where_pred.as_trait_clause() && let Some(failed_pred) = failed_pred.as_trait_clause() && where_pred.def_id() == failed_pred.def_id() @@ -4687,7 +4695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Extract `::Target` assoc type and check that it is `T` && let Some(deref_target_did) = tcx.lang_items().deref_target() && let projection = Ty::new_projection_from_args(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)])) - && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection) + && let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(projection)) && obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation)) && infcx.can_eq(param_env, deref_target, target_ty) { @@ -5300,7 +5308,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.probe(|_| { let ocx = ObligationCtxt::new(self); self.enter_forall(pred, |pred| { - let pred = ocx.normalize(&ObligationCause::dummy(), param_env, pred); + let pred = ocx.normalize( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip(pred), + ); ocx.register_obligation(Obligation::new( self.tcx, ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index bc7bdd372baa6..28b9bf21eee59 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -80,6 +80,7 @@ pub fn opaque_type_has_defining_use_args<'tcx>( .tcx .type_of_opaque_hir_typeck(opaque_type_key.def_id) .instantiate_identity() + .skip_norm_wip() .error_reported()?; } diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index debc4fda15a56..e2123ace5a95d 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -4,7 +4,7 @@ use rustc_infer::infer::{InferCtxt, RegionResolutionError}; use rustc_macros::extension; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::{self, Ty, elaborate}; +use rustc_middle::ty::{self, Ty, Unnormalized, elaborate}; use crate::traits::ScrubbedTraitError; use crate::traits::outlives_bounds::InferCtxtExt; @@ -34,7 +34,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { if infcx.next_trait_solver() { match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( infcx.at(&ObligationCause::dummy(), param_env), - type_outlives, + Unnormalized::new_wip(type_outlives), ) { Ok(new) => type_outlives = new, Err(_) => { @@ -107,7 +107,7 @@ impl<'tcx> InferCtxt<'tcx> { &ObligationCause::dummy_with_span(origin.span()), outlives_env.param_env, ), - ty, + Unnormalized::new_wip(ty), ) .map_err(|_: Vec>| NoSolution) } else { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 77834320dbc6b..1891dd2dea02e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -9,7 +9,7 @@ use rustc_infer::traits::{ }; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; use rustc_middle::{bug, span_bug}; use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _}; use tracing::{instrument, trace}; @@ -35,7 +35,7 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>( ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, expected_ty)) => { let ct_ty = match ct.kind() { ty::ConstKind::Unevaluated(uv) => { - infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) + infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args).skip_norm_wip() } ty::ConstKind::Param(param_ct) => { param_ct.find_const_ty_from_env(obligation.param_env) @@ -626,11 +626,12 @@ fn derive_host_cause<'tcx>( .into_iter() .chain(tcx.const_conditions(impl_def_id).instantiate_identity(tcx).into_iter().map( |(trait_ref, span)| { + let trait_ref = trait_ref.skip_norm_wip(); ( - trait_ref.to_host_effect_clause( + Unnormalized::new_wip(trait_ref.to_host_effect_clause( tcx, parent_host_pred.skip_binder().constness, - ), + )), span, ) }, diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 567f660a59383..996d54dfb4a6f 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -8,7 +8,7 @@ use rustc_infer::traits::{FromSolverError, Obligation, TraitEngine}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, UniverseIndex, + TypeVisitableExt, UniverseIndex, Unnormalized, }; use tracing::instrument; @@ -19,12 +19,15 @@ use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; /// Deeply normalize all aliases in `value`. This does not handle inference and expects /// its input to be already fully resolved. -pub fn deeply_normalize<'tcx, T, E>(at: At<'_, 'tcx>, value: T) -> Result> +pub fn deeply_normalize<'tcx, T, E>( + at: At<'_, 'tcx>, + value: Unnormalized<'tcx, T>, +) -> Result> where T: TypeFoldable>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { - assert!(!value.has_escaping_bound_vars()); + assert!(!value.probe(|v| v.has_escaping_bound_vars())); deeply_normalize_with_skipped_universes(at, value, vec![]) } @@ -36,7 +39,7 @@ where /// `normalize_erasing_regions`, which skips binders as it walks through a type. pub fn deeply_normalize_with_skipped_universes<'tcx, T, E>( at: At<'_, 'tcx>, - value: T, + value: Unnormalized<'tcx, T>, universes: Vec>, ) -> Result> where @@ -63,13 +66,14 @@ where /// the underlying infcx has any stalled coroutine def ids. pub fn deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals<'tcx, T, E>( at: At<'_, 'tcx>, - value: T, + value: Unnormalized<'tcx, T>, universes: Vec>, ) -> Result<(T, Vec>>), Vec> where T: TypeFoldable>, E: FromSolverError<'tcx, NextSolverError<'tcx>>, { + let value = value.inside_norm(); let fulfill_cx = FulfillmentCtxt::new(at.infcx); let mut folder = NormalizationFolder { at, @@ -267,7 +271,7 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, let result: Result<_, Vec>> = infcx.commit_if_ok(|_| { deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( self.at, - ty, + Unnormalized::new_wip(ty), vec![None; ty.outer_exclusive_binder().as_usize()], ) }); @@ -282,7 +286,7 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, let result: Result<_, Vec>> = infcx.commit_if_ok(|_| { deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( self.at, - ct, + Unnormalized::new_wip(ct), vec![None; ct.outer_exclusive_binder().as_usize()], ) }); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a5d33c7f61a59..61ed05d873dd5 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -21,6 +21,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + Unnormalized, }; pub use rustc_next_trait_solver::coherence::*; use rustc_next_trait_solver::solve::SolverDelegateEvalExt; @@ -209,13 +210,14 @@ fn fresh_impl_header<'tcx>( ImplHeader { impl_def_id, impl_args, - self_ty: tcx.type_of(impl_def_id).instantiate(tcx, impl_args), - trait_ref: is_of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args)), + self_ty: tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(), + trait_ref: is_of_trait + .then(|| tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip()), predicates: tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_args) .iter() - .map(|(c, _)| c.as_predicate()) + .map(|(c, _)| c.skip_norm_wip().as_predicate()) .collect(), } } @@ -229,7 +231,7 @@ fn fresh_impl_header_normalized<'tcx>( let header = fresh_impl_header(infcx, impl_def_id, is_of_trait); let InferOk { value: mut header, obligations } = - infcx.at(&ObligationCause::dummy(), param_env).normalize(header); + infcx.at(&ObligationCause::dummy(), param_env).normalize(Unnormalized::new_wip(header)); header.predicates.extend(obligations.into_iter().map(|o| o.predicate)); header @@ -535,12 +537,19 @@ fn impl_intersection_has_negative_obligation( // So there are no infer variables left now, except regions which aren't resolved by `resolve_vars_if_possible`. assert!(!impl1_header_args.has_non_region_infer()); - let param_env = - ty::EarlyBinder::bind(tcx.param_env(impl1_def_id)).instantiate(tcx, impl1_header_args); - - util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args)) - .elaborate_sized() - .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env)) + let param_env = ty::EarlyBinder::bind(tcx.param_env(impl1_def_id)) + .instantiate(tcx, impl1_header_args) + .skip_norm_wip(); + + util::elaborate( + tcx, + tcx.predicates_of(impl2_def_id) + .instantiate(tcx, impl2_header.impl_args) + .into_iter() + .map(|(c, s)| (c.skip_norm_wip(), s)), + ) + .elaborate_sized() + .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env)) } fn plug_infer_with_placeholders<'tcx>( @@ -791,7 +800,11 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { if matches!(ty.kind(), ty::Alias(..)) { let ocx = ObligationCtxt::new(infcx); ty = ocx - .structurally_normalize_ty(&ObligationCause::dummy(), param_env, ty) + .structurally_normalize_ty( + &ObligationCause::dummy(), + param_env, + Unnormalized::new_wip(ty), + ) .map_err(|_| ())?; if !ocx.try_evaluate_obligations().is_empty() { return Err(()); diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 1ca0aa3bab199..bd587f775c863 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -13,8 +13,8 @@ use rustc_hir::{self as hir, LangItem}; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast, - elaborate, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, + Upcast, elaborate, }; use rustc_span::{DUMMY_SP, Span}; use smallvec::SmallVec; @@ -200,7 +200,11 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span .filter(|item| item.is_type()) // Ignore GATs with `Self: Sized` .filter(|item| !tcx.generics_require_sized_self(item.def_id)) - .flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied()) + .flat_map(|item| { + tcx.explicit_item_bounds(item.def_id) + .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) + }) .filter_map(|(clause, sp)| { // Item bounds *can* have self projections, since they never get // their self type erased. @@ -258,6 +262,7 @@ fn super_predicates_have_non_lifetime_binders( ) -> SmallVec<[Span; 1]> { tcx.explicit_super_predicates_of(trait_def_id) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(span)) .collect() } @@ -271,6 +276,7 @@ fn super_predicates_are_unconditionally_const( ) -> SmallVec<[Span; 1]> { tcx.explicit_super_predicates_of(trait_def_id) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .filter_map(|(pred, span)| { if let ty::ClauseKind::HostEffect(_) = pred.kind().skip_binder() { Some(span) @@ -291,8 +297,13 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { }; // Search for a predicate like `Self: Sized` amongst the trait bounds. - let predicates = tcx.predicates_of(def_id); - let predicates = predicates.instantiate_identity(tcx).predicates; + let predicates: Vec<_> = tcx + .predicates_of(def_id) + .instantiate_identity(tcx) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); elaborate(tcx, predicates).any(|pred| match pred.kind().skip_binder() { ty::ClauseKind::Trait(ref trait_pred) => { trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) @@ -341,7 +352,9 @@ pub fn dyn_compatibility_violations_for_assoc_item( errors.push(AssocConstViolation::NonType); } - let ty = ty::Binder::dummy(tcx.type_of(item.def_id).instantiate_identity()); + let ty = ty::Binder::dummy( + tcx.type_of(item.def_id).instantiate_identity().skip_norm_wip(), + ); if contains_illegal_self_type_reference( tcx, trait_def_id, @@ -403,7 +416,7 @@ fn virtual_call_violations_for_method<'tcx>( trait_def_id: DefId, method: ty::AssocItem, ) -> Vec { - let sig = tcx.fn_sig(method.def_id).instantiate_identity(); + let sig = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip(); // The method's first parameter must be named `self` if !method.is_method() { @@ -569,7 +582,7 @@ fn receiver_for_self_ty<'tcx>( if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) } }); - let result = EarlyBinder::bind(receiver_ty).instantiate(tcx, args); + let result = EarlyBinder::bind(receiver_ty).instantiate(tcx, args).skip_norm_wip(); debug!( "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", receiver_ty, self_ty, method_def_id, result @@ -668,7 +681,13 @@ fn receiver_is_dispatchable<'tcx>( // are not constructing a param-env for "inside" of the body of the defaulted // method, so we don't really care about projecting to a specific RPIT type, // and because RPITITs are not dyn compatible (yet). - let mut predicates = tcx.predicates_of(method.def_id).instantiate_identity(tcx).predicates; + let mut predicates: Vec<_> = tcx + .predicates_of(method.def_id) + .instantiate_identity(tcx) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); // Self: Unsize let unsize_predicate = diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 9959c92a6f897..3033750eaccde 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -8,7 +8,7 @@ use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::elaborate::elaborate; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, Unnormalized}; use thin_vec::{ThinVec, thin_vec}; use super::SelectionContext; @@ -190,6 +190,7 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>( tcx, tcx.explicit_implied_const_bounds(def_id) .iter_instantiated_copied(tcx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) .map(|(trait_ref, _)| { trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness) }), @@ -234,14 +235,22 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>( Ok(match_candidate(selcx, obligation, data, true, |selcx, nested| { // An alias bound only holds if we also check the const conditions // of the alias, so we need to register those, too. - let const_conditions = normalize_with_depth_to( - selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth, - tcx.const_conditions(alias_ty.kind.def_id()).instantiate(tcx, alias_ty.args), - nested, - ); + let const_conditions = + tcx.const_conditions(alias_ty.kind.def_id()).instantiate(tcx, alias_ty.args); + let const_conditions: Vec<_> = const_conditions + .into_iter() + .map(|(trait_ref, span)| { + let trait_ref = normalize_with_depth_to( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth, + trait_ref.skip_norm_wip(), + nested, + ); + (trait_ref, span) + }) + .collect(); nested.extend(const_conditions.into_iter().map(|(trait_ref, _)| { obligation .with(tcx, trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness)) @@ -272,7 +281,11 @@ fn evaluate_host_effect_from_item_bounds<'tcx>( }, ) = *consider_ty.kind() { - for clause in tcx.item_bounds(def_id).iter_instantiated(tcx, alias_ty.args) { + for clause in tcx + .item_bounds(def_id) + .iter_instantiated(tcx, alias_ty.args) + .map(Unnormalized::skip_norm_wip) + { let bound_clause = clause.kind(); let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else { continue; @@ -411,6 +424,7 @@ fn evaluate_host_effect_for_copy_clone_goal<'tcx>( ty::CoroutineWitness(def_id, args) => Ok(tcx .coroutine_hidden_types(def_id) .instantiate(tcx, args) + .skip_norm_wip() .map_bound(|bound| bound.types.to_vec())), }?; @@ -563,6 +577,7 @@ fn evaluate_host_effect_for_fn_goal<'tcx>( .instantiate(tcx, args) .into_iter() .map(|(c, span)| { + let c = c.skip_norm_wip(); let code = ObligationCauseCode::WhereClause(def, span); let cause = ObligationCause::new(obligation.cause.span, obligation.cause.body_id, code); @@ -599,6 +614,7 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>( .instantiate(tcx, impl_.args) .into_iter() .map(|(trait_ref, span)| { + let trait_ref = trait_ref.skip_norm_wip(); Obligation::new( tcx, obligation.cause.clone().derived_host_cause( @@ -643,6 +659,7 @@ fn evaluate_host_effect_from_trait_alias<'tcx>( .instantiate(tcx, obligation.predicate.trait_ref.args) .into_iter() .map(|(trait_ref, span)| { + let trait_ref = trait_ref.skip_norm_wip(); Obligation::new( tcx, obligation.cause.clone().derived_host_cause( diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index eee23a298449d..6cddd79544906 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -15,7 +15,7 @@ use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::Relate; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast, Variance}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast, Variance}; use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine}; use crate::error_reporting::InferCtxtErrorExt; @@ -113,7 +113,7 @@ where &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: Unnormalized<'tcx, T>, ) -> T { let infer_ok = self.infcx.at(cause, param_env).normalize(value); self.register_infer_ok_obligations(infer_ok) @@ -331,7 +331,7 @@ where match self .infcx .at(&cause, param_env) - .deeply_normalize(ty, &mut **self.engine.borrow_mut()) + .deeply_normalize(Unnormalized::new_wip(ty), &mut **self.engine.borrow_mut()) { // Insert well-formed types, ignoring duplicates. Ok(normalized) => drop(implied_bounds.insert(normalized)), @@ -346,7 +346,7 @@ where &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: Unnormalized<'tcx, T>, ) -> Result> { self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut()) } @@ -355,7 +355,7 @@ where &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: Ty<'tcx>, + value: Unnormalized<'tcx, Ty<'tcx>>, ) -> Result, Vec> { self.infcx .at(cause, param_env) @@ -366,7 +366,7 @@ where &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: ty::Const<'tcx>, + value: Unnormalized<'tcx, ty::Const<'tcx>>, ) -> Result, Vec> { self.infcx .at(cause, param_env) @@ -377,7 +377,7 @@ where &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: ty::Term<'tcx>, + value: Unnormalized<'tcx, ty::Term<'tcx>>, ) -> Result, Vec> { self.infcx .at(cause, param_env) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2dbeff4a50508..88cb18e5d3678 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -523,9 +523,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { return ProcessResult::Changed(PendingPredicateObligations::new()); } ty::ConstKind::Value(cv) => cv.ty, - ty::ConstKind::Unevaluated(uv) => { - infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) - } + ty::ConstKind::Unevaluated(uv) => infcx + .tcx + .type_of(uv.def) + .instantiate(infcx.tcx, uv.args) + .skip_norm_wip(), // FIXME(generic_const_exprs): we should construct an alias like // `>::Output` when this is an `Expr` representing // `lhs + rhs`. diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 2fd3a6e738cfe..bd0068c19886f 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -4,7 +4,7 @@ use hir::LangItem; use rustc_ast::Mutability; use rustc_hir as hir; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized}; use rustc_span::sym; use crate::regions::InferCtxtRegionExt; @@ -234,7 +234,11 @@ pub fn all_fields_implement_trait<'tcx>( } else { ObligationCause::dummy_with_span(field_ty_span) }; - let ty = ocx.normalize(&normalization_cause, param_env, unnormalized_ty); + let ty = ocx.normalize( + &normalization_cause, + param_env, + Unnormalized::new_wip(unnormalized_ty), + ); let normalization_errors = ocx.try_evaluate_obligations(); // NOTE: The post-normalization type may also reference errors, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 89a6132b0dc7f..0196b8bee7cca 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -35,7 +35,8 @@ use rustc_middle::span_bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, Clause, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Upcast, + TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, + Unnormalized, Upcast, }; use rustc_span::Span; use rustc_span::def_id::DefId; @@ -180,7 +181,7 @@ pub enum TraitQueryMode { #[instrument(level = "debug", skip(cause, param_env, normalize_predicate))] pub fn predicates_for_generics<'tcx>( cause: impl Fn(usize, Span) -> ObligationCause<'tcx>, - mut normalize_predicate: impl FnMut(Clause<'tcx>) -> Clause<'tcx>, + mut normalize_predicate: impl FnMut(Unnormalized<'tcx, Clause<'tcx>>) -> Clause<'tcx>, param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { @@ -274,7 +275,7 @@ fn do_normalize_predicates<'tcx>( // we move over to lazy normalization *anyway*. let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - let predicates = ocx.normalize(&cause, elaborated_env, predicates); + let predicates = ocx.normalize(&cause, elaborated_env, Unnormalized::new_wip(predicates)); let errors = ocx.evaluate_obligations_error_on_ambiguity(); if !errors.is_empty() { @@ -505,7 +506,7 @@ pub fn deeply_normalize_param_env_ignoring_regions<'tcx>( .build(TypingMode::non_body_analysis()); let predicates = match crate::solve::deeply_normalize::<_, FulfillmentError<'tcx>>( infcx.at(&cause, elaborated_env), - predicates, + Unnormalized::new_wip(predicates), ) { Ok(predicates) => predicates, Err(errors) => { @@ -626,7 +627,9 @@ pub fn try_evaluate_const<'tcx>( // does not actually make use of them. We handle this case specially and attempt to evaluate anyway. match tcx.thir_abstract_const(uv.def) { Ok(Some(ct)) => { - let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args)); + let ct = tcx.expand_abstract_consts( + ct.instantiate(tcx, uv.args).skip_norm_wip(), + ); if let Err(e) = ct.error_reported() { return Err(EvaluateConstErr::EvaluationFailure(e)); } else if ct.has_non_region_infer() || ct.has_non_region_param() { @@ -715,7 +718,7 @@ pub fn try_evaluate_const<'tcx>( Ok(Ok(val)) => Ok(ty::Const::new_value( tcx, val, - tcx.type_of(uv.def).instantiate(tcx, uv.args), + tcx.type_of(uv.def).instantiate(tcx, uv.args).skip_norm_wip(), )), Ok(Err(_)) => { let e = tcx.dcx().delayed_bug( @@ -794,7 +797,8 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec( ) -> bool { debug!("instantiate_and_check_impossible_predicates(key={:?})", key); - let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; + let mut predicates: Vec<_> = tcx + .predicates_of(key.0) + .instantiate(tcx, key.1) + .predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .collect(); // Specifically check trait fulfillment to avoid an error when trying to resolve // associated items. @@ -896,7 +906,8 @@ fn is_impossible_associated_item( let param_env = ty::ParamEnv::empty(); let fresh_args = infcx.fresh_args_for_item(tcx.def_span(impl_def_id), impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_args); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_args).skip_norm_wip(); let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { @@ -905,7 +916,7 @@ fn is_impossible_associated_item( tcx, ObligationCause::dummy_with_span(*span), param_env, - ty::EarlyBinder::bind(*pred).instantiate(tcx, impl_trait_ref.args), + ty::EarlyBinder::bind(*pred).instantiate(tcx, impl_trait_ref.args).skip_norm_wip(), ) }) }); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 65c4b40d43964..68c68df7c658c 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -13,7 +13,7 @@ use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ self, AliasTerm, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, - TypeVisitableExt, TypingMode, + TypeVisitableExt, TypingMode, Unnormalized, }; use tracing::{debug, instrument}; @@ -28,7 +28,11 @@ impl<'tcx> At<'_, 'tcx> { /// /// This normalization should be used when the type contains inference variables or the /// projection may be fallible. - fn normalize>>(&self, value: T) -> InferOk<'tcx, T> { + fn normalize>>( + &self, + value: Unnormalized<'tcx, T>, + ) -> InferOk<'tcx, T> { + let value = value.inside_norm(); if self.infcx.next_trait_solver() { InferOk { value, obligations: PredicateObligations::new() } } else { @@ -53,7 +57,7 @@ impl<'tcx> At<'_, 'tcx> { /// can remove the `fulfill_cx` parameter on this function. fn deeply_normalize( self, - value: T, + value: Unnormalized<'tcx, T>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, ) -> Result> where @@ -315,8 +319,12 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { // that other kinds of normalization do. let infcx = self.selcx.infcx; self.obligations.extend( - infcx.tcx.predicates_of(free.def_id).instantiate_own(infcx.tcx, free.args).map( - |(mut predicate, span)| { + infcx + .tcx + .predicates_of(free.def_id) + .instantiate_own(infcx.tcx, free.args) + .map(|(pred, span)| (pred.skip_norm_wip(), span)) + .map(|(mut predicate, span)| { if free.has_escaping_bound_vars() { (predicate, ..) = BoundVarReplacer::replace_bound_vars( infcx, @@ -327,17 +335,23 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { let mut cause = self.cause.clone(); cause.map_code(|code| ObligationCauseCode::TypeAlias(code, span, free.def_id)); Obligation::new(infcx.tcx, cause, self.param_env, predicate) - }, - ), + }), ); self.depth += 1; let res = if free.kind(infcx.tcx).is_type() { - infcx.tcx.type_of(free.def_id).instantiate(infcx.tcx, free.args).fold_with(self).into() + infcx + .tcx + .type_of(free.def_id) + .instantiate(infcx.tcx, free.args) + .skip_norm_wip() + .fold_with(self) + .into() } else { infcx .tcx .const_of_item(free.def_id) .instantiate(infcx.tcx, free.args) + .skip_norm_wip() .fold_with(self) .into() }; @@ -413,7 +427,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let args = data.args.fold_with(self); let generic_ty = self.cx().type_of(def_id); - let concrete_ty = generic_ty.instantiate(self.cx(), args); + let concrete_ty = generic_ty.instantiate(self.cx(), args).skip_norm_wip(); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 72d3ba9629f4d..6c1f3a83c9552 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -520,7 +520,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( param_env, cause.clone(), depth + 1, - predicate, + predicate.skip_norm_wip(), obligations, ); @@ -544,9 +544,9 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( } let term: Term<'tcx> = if alias_term.kind(tcx).is_type() { - tcx.type_of(alias_term.def_id).instantiate(tcx, args).into() + tcx.type_of(alias_term.def_id).instantiate(tcx, args).skip_norm_wip().into() } else { - tcx.const_of_item(alias_term.def_id).instantiate(tcx, args).into() + tcx.const_of_item(alias_term.def_id).instantiate(tcx, args).skip_norm_wip().into() }; let mut term = selcx.infcx.resolve_vars_if_possible(term); @@ -572,7 +572,7 @@ pub fn compute_inherent_assoc_term_args<'a, 'b, 'tcx>( let impl_def_id = tcx.parent(alias_term.def_id); let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id); - let mut impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args); + let mut impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip(); if !selcx.infcx.next_trait_solver() { impl_ty = normalize_with_depth_to( selcx, @@ -2061,7 +2061,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( Progress { term: err, obligations: nested } } else { assoc_term_own_obligations(selcx, obligation, &mut nested); - Progress { term: term.instantiate(tcx, args), obligations: nested } + Progress { term: term.instantiate(tcx, args).skip_norm_wip(), obligations: nested } }; Ok(Projected::Progress(progress)) } @@ -2087,7 +2087,7 @@ fn assoc_term_own_obligations<'cx, 'tcx>( obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - predicate, + predicate.skip_norm_wip(), nested, ); diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 8a61d9a021752..6a6ade3b23b36 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_infer::traits::query::type_op::DropckOutlives; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; -use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt, Unnormalized}; use rustc_span::Span; use tracing::{debug, instrument}; @@ -208,7 +208,7 @@ where // reason that we could use to report an error in borrowck. In order to turn // this into a reportable error, we deeply normalize again. We don't expect // this to succeed, so delay a bug if it does. - match ocx.deeply_normalize(&cause, param_env, ty) { + match ocx.deeply_normalize(&cause, param_env, Unnormalized::new_wip(ty)) { Ok(_) => { tcx.dcx().span_delayed_bug( span, @@ -388,15 +388,21 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( tcx.at(span).adt_dtorck_constraint(def.did()); // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. - constraints - .dtorck_types - .extend(dtorck_types.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args))); - constraints - .outlives - .extend(outlives.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args))); - constraints - .overflows - .extend(overflows.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args))); + constraints.dtorck_types.extend( + dtorck_types + .iter() + .map(|t| EarlyBinder::bind(*t).instantiate(tcx, args).skip_norm_wip()), + ); + constraints.outlives.extend( + outlives + .iter() + .map(|t| EarlyBinder::bind(*t).instantiate(tcx, args).skip_norm_wip()), + ); + constraints.overflows.extend( + overflows + .iter() + .map(|t| EarlyBinder::bind(*t).instantiate(tcx, args).skip_norm_wip()), + ); } // Objects must be alive in order for their destructor diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a088384146293..2576b0af92831 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -10,7 +10,7 @@ use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::{ self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, }; use rustc_span::DUMMY_SP; use tracing::{debug, info, instrument}; @@ -79,7 +79,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { if self.infcx.next_trait_solver() { match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>( - self, value, universes, + self, + Unnormalized::new_wip(value), + universes, ) { Ok(value) => { return Ok(Normalized { value, obligations: PredicateObligations::new() }); @@ -237,7 +239,8 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { } let generic_ty = self.cx().type_of(data.kind.def_id()); - let mut concrete_ty = generic_ty.instantiate(self.cx(), args); + let mut concrete_ty = + generic_ty.instantiate(self.cx(), args).skip_norm_wip(); self.anon_depth += 1; if concrete_ty == ty { concrete_ty = Ty::new_error_with_message( diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index c4353fe25b85b..1d5c6be2687f0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -4,7 +4,9 @@ use rustc_infer::traits::Obligation; use rustc_middle::traits::query::NoSolution; pub use rustc_middle::traits::query::type_op::AscribeUserType; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserTypeKind}; +use rustc_middle::ty::{ + self, ParamEnvAnd, Ty, TyCtxt, Unnormalized, UserArgs, UserSelfTy, UserTypeKind, +}; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument}; @@ -78,7 +80,7 @@ fn relate_mir_and_user_ty<'tcx>( ty::ClauseKind::WellFormed(user_ty.into()), )); - let user_ty = ocx.normalize(&cause, param_env, user_ty); + let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty)); ocx.eq(&cause, param_env, mir_ty, user_ty)?; Ok(()) @@ -108,7 +110,8 @@ fn relate_mir_and_user_args<'tcx>( let impl_args = ocx.infcx.fresh_args_for_item(span, impl_def_id); let impl_self_ty = ocx.normalize(&cause, param_env, tcx.type_of(impl_def_id).instantiate(tcx, impl_args)); - let user_self_ty = ocx.normalize(&cause, param_env, args[0].expect_ty()); + let user_self_ty = + ocx.normalize(&cause, param_env, Unnormalized::new_wip(args[0].expect_ty())); ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?; let gat_args = &args[1..]; @@ -169,9 +172,9 @@ fn relate_mir_and_user_args<'tcx>( ty::ClauseKind::WellFormed(self_ty.into()), )); - let self_ty = ocx.normalize(&cause, param_env, self_ty); - let impl_self_ty = tcx.type_of(impl_def_id).instantiate(tcx, args); - let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); + let self_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(self_ty)); + let impl_self_ty = tcx.type_of(impl_def_id).instantiate(tcx, args).skip_norm_wip(); + let impl_self_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(impl_self_ty)); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 47ff6190fa4f7..233e124fc60f5 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::outlives::{Component, push_outlives_components}; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitable, TypeVisitor, Unnormalized}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{DUMMY_SP, Span, sym}; use smallvec::{SmallVec, smallvec}; @@ -73,7 +73,11 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // for example, if we have some constrained param type like `T: Trait`, // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`. let normalized_ty = ocx - .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty) + .deeply_normalize( + &ObligationCause::dummy_with_span(span), + param_env, + Unnormalized::new_wip(ty), + ) .map_err(|_| NoSolution)?; // Sometimes when we ask what it takes for T: WF, we get back that @@ -101,7 +105,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( .deeply_normalize( &ObligationCause::dummy_with_span(span), param_env, - obligation.predicate, + Unnormalized::new_wip(obligation.predicate), ) .map_err(|_| NoSolution)?; let Some(pred) = pred.kind().no_bound_vars() else { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index f2a6ce855b49d..1b8a02f78b579 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -3,7 +3,9 @@ use std::fmt; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; pub use rustc_middle::traits::query::type_op::{DeeplyNormalize, Normalize}; -use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; +use rustc_middle::ty::{ + self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Unnormalized, +}; use rustc_span::Span; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; @@ -71,7 +73,7 @@ where ocx.deeply_normalize( &ObligationCause::dummy_with_span(span), key.param_env, - key.value.value, + Unnormalized::new_wip(key.value.value), ) .map_err(|_| NoSolution) } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e948994b8689c..11ce6235eb7ff 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -14,7 +14,9 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{ + self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Unnormalized, Upcast, +}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use thin_vec::thin_vec; @@ -537,6 +539,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { for (supertrait, _) in tcx .explicit_super_predicates_of(trait_predicate.def_id()) .iter_instantiated_copied(tcx, trait_predicate.trait_ref.args) + .map(Unnormalized::skip_norm_wip) { let normalized_supertrait = normalize_with_depth_to( self, @@ -578,7 +581,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - bound.instantiate(tcx, trait_predicate.trait_ref.args), + bound.instantiate(tcx, trait_predicate.trait_ref.args).skip_norm_wip(), &mut nested, ); nested.push(obligation.with(tcx, normalized_bound)); @@ -1179,7 +1182,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - tail_field_ty.instantiate(tcx, args_a), + tail_field_ty.instantiate(tcx, args_a).skip_norm_wip(), &mut nested, ); let target_tail = normalize_with_depth_to( @@ -1187,7 +1190,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - tail_field_ty.instantiate(tcx, args_b), + tail_field_ty.instantiate(tcx, args_b).skip_norm_wip(), &mut nested, ); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a564e8060d930..17a5f14767eec 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -27,8 +27,8 @@ use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ self, CandidatePreferenceMode, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, - SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate, - may_use_unstable_feature, + SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, + elaborate, may_use_unstable_feature, }; use rustc_next_trait_solver::solve::AliasBoundKind; use rustc_span::Symbol; @@ -981,9 +981,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::ConstKind::Error(_) => return Ok(EvaluatedToOk), ty::ConstKind::Value(cv) => cv.ty, - ty::ConstKind::Unevaluated(uv) => { - self.tcx().type_of(uv.def).instantiate(self.tcx(), uv.args) - } + ty::ConstKind::Unevaluated(uv) => self + .tcx() + .type_of(uv.def) + .instantiate(self.tcx(), uv.args) + .skip_norm_wip(), // FIXME(generic_const_exprs): See comment in `fulfill.rs` ty::ConstKind::Expr(_) => return Ok(EvaluatedToOk), ty::ConstKind::Placeholder(_) => { @@ -1669,7 +1671,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().item_self_bounds(def_id) }; - for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args) { + for bound in relevant_bounds.instantiate(self.tcx(), alias_ty.args).skip_norm_wip() { for_each(self, bound, idx, alias_bound_kind)?; idx += 1; } @@ -2184,7 +2186,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ty::Adt(def, args) => { if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) { - ty::Binder::dummy(vec![crit.instantiate(self.tcx(), args)]) + ty::Binder::dummy(vec![crit.instantiate(self.tcx(), args).skip_norm_wip()]) } else { ty::Binder::dummy(vec![]) } @@ -2256,6 +2258,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { .tcx .coroutine_hidden_types(def_id) .instantiate(self.infcx.tcx, args) + .skip_norm_wip() .map_bound(|witness| witness.types.to_vec()), ty::Closure(_, args) => ty::Binder::dummy(args.as_closure().upvar_tys().to_vec()), @@ -2388,6 +2391,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { .tcx .coroutine_hidden_types(def_id) .instantiate(self.infcx.tcx, args) + .skip_norm_wip() .map_bound(|witness| AutoImplConstituents { types: witness.types.to_vec(), assumptions: witness.assumptions.to_vec(), @@ -2415,7 +2419,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // the auto trait bounds in question. let ty = self.tcx().type_of_opaque(def_id); ty::Binder::dummy(AutoImplConstituents { - types: vec![ty.instantiate(self.tcx(), args)], + types: vec![ty.instantiate(self.tcx(), args).skip_norm_wip()], assumptions: vec![], }) } @@ -2518,7 +2522,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); - let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args); + let trait_ref = + impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args).skip_norm_wip(); debug!(?impl_trait_header); let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = @@ -2850,7 +2855,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { param_env, cause.clone(), recursion_depth, - predicate, + predicate.skip_norm_wip(), &mut obligations, ); obligations.push(Obligation { @@ -2863,7 +2868,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // Register any outlives obligations from the trait here, cc #124336. if tcx.def_kind(def_id) == (DefKind::Impl { of_trait: true }) { - for clause in tcx.impl_super_outlives(def_id).iter_instantiated(tcx, args) { + for clause in tcx + .impl_super_outlives(def_id) + .iter_instantiated(tcx, args) + .map(Unnormalized::skip_norm_wip) + { let clause = normalize_with_depth_to( self, param_env, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index d6dcb97562d04..164d01a3285e6 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -20,7 +20,9 @@ use rustc_middle::bug; use rustc_middle::query::LocalCrate; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::print::PrintTraitRefExt as _; -use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{ + self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, +}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym}; use specialization_graph::GraphExt; @@ -117,7 +119,7 @@ pub fn translate_args_with_cause<'tcx>( param_env, source_impl, source_args, target_node ); let source_trait_ref = - infcx.tcx.impl_trait_ref(source_impl).instantiate(infcx.tcx, source_args); + infcx.tcx.impl_trait_ref(source_impl).instantiate(infcx.tcx, source_args).skip_norm_wip(); // translate the Self and Param parts of the generic parameters, since those // vary across impls @@ -162,7 +164,7 @@ fn fulfill_implication<'tcx>( ); let ocx = ObligationCtxt::new(infcx); - let source_trait_ref = ocx.normalize(cause, param_env, source_trait_ref); + let source_trait_ref = ocx.normalize(cause, param_env, Unnormalized::new_wip(source_trait_ref)); if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { infcx.dcx().span_delayed_bug( @@ -348,11 +350,11 @@ pub(super) fn specializes( return false; } - let const_conditions = ocx.normalize( - cause, - param_env, - infcx.tcx.const_conditions(parent_impl_def_id).instantiate(infcx.tcx, parent_args), - ); + let const_conditions = + infcx.tcx.const_conditions(parent_impl_def_id).instantiate(infcx.tcx, parent_args); + let const_conditions = const_conditions + .into_iter() + .map(|(trait_ref, span)| (ocx.normalize(cause, param_env, trait_ref), span)); ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, _)| { Obligation::new( infcx.tcx, diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index ebeab8eddc6f5..cce5f9c84ecc4 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,7 +1,7 @@ use rustc_infer::infer::at::At; use rustc_infer::traits::TraitEngine; use rustc_macros::extension; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, Unnormalized}; use crate::traits::{NormalizeExt, Obligation}; @@ -9,32 +9,35 @@ use crate::traits::{NormalizeExt, Obligation}; impl<'tcx> At<'_, 'tcx> { fn structurally_normalize_ty( &self, - ty: Ty<'tcx>, + ty: Unnormalized<'tcx, Ty<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, ) -> Result, Vec> { - self.structurally_normalize_term(ty.into(), fulfill_cx).map(|term| term.expect_type()) + self.structurally_normalize_term(ty.map_inner(Into::into), fulfill_cx) + .map(|term| term.expect_type()) } fn structurally_normalize_const( &self, - ct: ty::Const<'tcx>, + ct: Unnormalized<'tcx, ty::Const<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, ) -> Result, Vec> { if self.infcx.tcx.features().generic_const_exprs() { - return Ok(super::evaluate_const(&self.infcx, ct, self.param_env)); + return Ok(super::evaluate_const(&self.infcx, ct.inside_norm(), self.param_env)); } - self.structurally_normalize_term(ct.into(), fulfill_cx).map(|term| term.expect_const()) + self.structurally_normalize_term(ct.map_inner(Into::into), fulfill_cx) + .map(|term| term.expect_const()) } fn structurally_normalize_term( &self, - term: ty::Term<'tcx>, + term: Unnormalized<'tcx, ty::Term<'tcx>>, fulfill_cx: &mut dyn TraitEngine<'tcx, E>, ) -> Result, Vec> { - assert!(!term.is_infer(), "should have resolved vars before calling"); + assert!(!term.probe(|v| v.is_infer()), "should have resolved vars before calling"); if self.infcx.next_trait_solver() { + let term = term.inside_norm(); if let None = term.to_alias_term() { return Ok(term); } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c3f46aa51c737..13209a204d862 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -10,7 +10,7 @@ use rustc_middle::bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ self, PolyTraitPredicate, PredicatePolarity, SizedTraitKind, TraitPredicate, TraitRef, Ty, - TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, }; pub use rustc_next_trait_solver::placeholder::BoundVarReplacer; use rustc_span::Span; @@ -52,6 +52,7 @@ pub fn expand_trait_aliases<'tcx>( queue.extend( tcx.explicit_super_predicates_of(trait_pred.def_id()) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .map(|(super_clause, span)| { let mut spans = spans.clone(); spans.push(span); diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 0383f23e2b4fe..e3e65150a6d6c 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -6,7 +6,8 @@ use rustc_infer::traits::util::PredicateSet; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Upcast, VtblEntry, + self, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, + VtblEntry, }; use rustc_span::DUMMY_SP; use smallvec::{SmallVec, smallvec}; @@ -123,6 +124,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( let mut direct_super_traits_iter = tcx .explicit_super_predicates_of(inner_most_trait_ref.def_id) .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) .filter_map(move |(pred, _)| { pred.instantiate_supertrait(tcx, ty::Binder::dummy(inner_most_trait_ref)) .as_trait_clause() @@ -235,7 +237,10 @@ fn vtable_entries<'tcx>( ) -> &'tcx [VtblEntry<'tcx>] { debug_assert!(!trait_ref.has_non_region_infer() && !trait_ref.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref), + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(trait_ref) + ), trait_ref, "vtable trait ref should be normalized" ); @@ -263,13 +268,15 @@ fn vtable_entries<'tcx>( // FIXME: Is this normalize needed? let args = tcx.normalize_erasing_regions( ty::TypingEnv::fully_monomorphized(), - GenericArgs::for_item(tcx, def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { .. } => { - trait_ref.args[param.index as usize] + Unnormalized::new_wip(GenericArgs::for_item(tcx, def_id, |param, _| { + match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } + | GenericParamDefKind::Const { .. } => { + trait_ref.args[param.index as usize] + } } - }), + })), ); // It's possible that the method relies on where-clauses that @@ -279,7 +286,7 @@ fn vtable_entries<'tcx>( let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args); if impossible_predicates( tcx, - predicates.map(|(predicate, _)| predicate).collect(), + predicates.map(|(predicate, _)| predicate.skip_norm_wip()).collect(), ) { debug!("vtable_entries: predicates do not hold"); return VtblEntry::Vacant; @@ -317,7 +324,10 @@ fn vtable_entries<'tcx>( pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRef<'tcx>) -> usize { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(key) + ), key, "vtable trait ref should be normalized" ); @@ -381,7 +391,10 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( ) -> Option { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); debug_assert_eq!( - tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + tcx.normalize_erasing_regions( + ty::TypingEnv::fully_monomorphized(), + Unnormalized::new_wip(key) + ), key, "upcasting trait refs should be normalized" ); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 377505ee5f0d2..c9c274990eb97 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -596,7 +596,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { cause, self.recursion_depth, self.param_env, - pred, + pred.skip_norm_wip(), ) }) .filter(|pred| !pred.has_escaping_bound_vars()) @@ -822,7 +822,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // perfect and there may be ways to abuse the fact that we // ignore requirements with escaping bound vars. That's a // more general issue however. - let fn_sig = tcx.fn_sig(did).instantiate(tcx, args); + let fn_sig = tcx.fn_sig(did).instantiate(tcx, args).skip_norm_wip(); fn_sig.output().skip_binder().visit_with(self); let obligations = self.nominal_obligations(did, args); @@ -1002,7 +1002,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { p.term.as_const().map(|ct| { let assoc_const_ty = tcx .type_of(p.projection_term.def_id) - .instantiate(tcx, p.projection_term.args); + .instantiate(tcx, p.projection_term.args) + .skip_norm_wip(); ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType( ct, assoc_const_ty, @@ -1134,8 +1135,10 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { let cause = self.cause(ObligationCauseCode::WellFormed(None)); self.out.extend(variant_def.fields.iter().zip(adt_val.fields).map( |(field_def, &field_val)| { - let field_ty = - tcx.type_of(field_def.did).instantiate(tcx, args); + let field_ty = tcx + .type_of(field_def.did) + .instantiate(tcx, args) + .skip_norm_wip(); let predicate = ty::PredicateKind::Clause( ty::ClauseKind::ConstArgHasType(field_val, field_ty), ); diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index f3b43541b7cbe..58445e9d639f7 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, @@ -27,7 +27,10 @@ pub(crate) fn codegen_select_candidate<'tcx>( ) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> { let PseudoCanonicalInput { typing_env, value: trait_ref } = key; // We expect the input to be fully normalized. - debug_assert_eq!(trait_ref, tcx.normalize_erasing_regions(typing_env, trait_ref)); + debug_assert_eq!( + trait_ref, + tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(trait_ref)) + ); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index d33ade7a9e15d..64af828aeb60c 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -54,7 +54,7 @@ pub(crate) fn adt_dtorck_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &DropckCo let mut result = DropckConstraint::empty(); for field in def.all_fields() { - let fty = tcx.type_of(field.did).instantiate_identity(); + let fty = tcx.type_of(field.did).instantiate_identity().skip_norm_wip(); dtorck_constraint_for_ty_inner(tcx, typing_env, span, 0, fty, &mut result); } result.outlives.extend(tcx.destructor_constraints(def)); diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 1d7ea9fe00a3f..13af5171dfc26 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -75,21 +75,23 @@ fn normalize_canonicalized_free_alias<'tcx>( tcx.infer_ctxt().enter_canonical_trait_query( &goal, |ocx, ParamEnvAnd { param_env, value: goal }| { - let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.args).map( - |(predicate, span)| { + let obligations = tcx + .predicates_of(goal.def_id) + .instantiate_own(tcx, goal.args) + .map(|(c, s)| (c.skip_norm_wip(), s)) + .map(|(predicate, span)| { traits::Obligation::new( tcx, ObligationCause::dummy_with_span(span), param_env, predicate, ) - }, - ); + }); ocx.register_obligations(obligations); let normalized_term = if goal.kind(tcx).is_type() { - tcx.type_of(goal.def_id).instantiate(tcx, goal.args).into() + tcx.type_of(goal.def_id).instantiate(tcx, goal.args).skip_norm_wip().into() } else { - tcx.const_of_item(goal.def_id).instantiate(tcx, goal.args).into() + tcx.const_of_item(goal.def_id).instantiate(tcx, goal.args).skip_norm_wip().into() }; Ok(NormalizationResult { normalized_term }) }, diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 5008794bcb191..2e7c7c7070b9d 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -10,7 +10,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ FnAbiError, HasTyCtxt, HasTypingEnv, LayoutCx, LayoutOf, TyAndLayout, fn_can_unwind, }; -use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, InstanceKind, Ty, TyCtxt, Unnormalized}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_target::callconv::{ @@ -51,8 +51,9 @@ fn fn_sig_for_fn_abi<'tcx>( let ty = instance.ty(tcx, typing_env); match *ty.kind() { ty::FnDef(def_id, args) => { - let mut sig = tcx - .instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)); + let mut sig = tcx.instantiate_bound_regions_with_erased( + tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(), + ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. if let ty::InstanceKind::VTableShim(..) = instance.def { @@ -268,7 +269,7 @@ impl<'tcx> FnAbiDesc<'tcx> { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( typing_env, - tcx.instantiate_bound_regions_with_erased(sig), + Unnormalized::new_wip(tcx.instantiate_bound_regions_with_erased(sig)), ), // Parameter attributes can never be deduced for indirect calls, as there is no // function body available to use. @@ -290,7 +291,7 @@ impl<'tcx> FnAbiDesc<'tcx> { layout_cx: LayoutCx::new(tcx, typing_env), sig: tcx.normalize_erasing_regions( typing_env, - fn_sig_for_fn_abi(tcx, instance, typing_env), + Unnormalized::new_wip(fn_sig_for_fn_abi(tcx, instance, typing_env)), ), // Parameter attributes can be deduced from the bodies of neither: // - virtual calls, as they might call other functions from the vtable; nor diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 09e7eb93504c3..659229a58d539 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt, fold_regions}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized, fold_regions}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; @@ -24,7 +24,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let kind = tcx.def_kind(def_id); match kind { DefKind::Fn => { - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); tcx.arena.alloc_from_iter(itertools::zip_eq( liberated_sig.inputs_and_output, @@ -32,7 +32,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' )) } DefKind::AssocFn => { - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let liberated_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); let mut assumed_wf_types: Vec<_> = tcx.assumed_wf_types(tcx.local_parent(def_id)).into(); @@ -49,7 +49,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let trait_ref = tcx.impl_trait_ref(def_id); trait_ref.skip_binder().args.types().collect() } else { - vec![tcx.type_of(def_id).instantiate_identity()] + vec![tcx.type_of(def_id).instantiate_identity().skip_norm_wip()] }; let mut impl_spans = impl_spans(tcx, def_id); @@ -113,11 +113,12 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( tcx, impl_def_id.to_def_id(), - tcx.impl_trait_ref(impl_def_id).instantiate_identity().args, + tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip().args, ); tcx.arena.alloc_from_iter( ty::EarlyBinder::bind(tcx.assumed_wf_types_for_rpitit(rpitit_def_id)) .iter_instantiated_copied(tcx, args) + .map(Unnormalized::skip_norm_wip) .chain(tcx.assumed_wf_types(impl_def_id).into_iter().copied()), ) } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index e48e525e571d0..3e1263ea9a022 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -7,6 +7,7 @@ use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; use rustc_middle::ty::{ self, ClosureKind, GenericArgsRef, Instance, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, + Unnormalized, }; use rustc_span::sym; use rustc_trait_selection::traits; @@ -28,7 +29,7 @@ fn resolve_instance_raw<'tcx>( def_id, typing_env, trait_def_id, - tcx.normalize_erasing_regions(typing_env, args), + tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(args)), ) } else { let def = if tcx.intrinsic(def_id).is_some() { @@ -194,10 +195,15 @@ fn resolve_associated_item<'tcx>( let sized_def_id = tcx.lang_items().sized_trait(); // If we find a `Self: Sized` bound on the item, then we know // that `dyn Trait` can certainly never apply here. - if !predicates.into_iter().filter_map(ty::Clause::as_trait_clause).any(|clause| { - Some(clause.def_id()) == sized_def_id - && clause.skip_binder().self_ty() == self_ty - }) { + if !predicates + .into_iter() + .map(Unnormalized::skip_norm_wip) + .filter_map(ty::Clause::as_trait_clause) + .any(|clause| { + Some(clause.def_id()) == sized_def_id + && clause.skip_binder().self_ty() == self_ty + }) + { return Ok(None); } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 136df923ee47a..716ecf5723839 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -19,7 +19,8 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, AdtDef, CoroutineArgsExt, EarlyBinder, PseudoCanonicalInput, Ty, TyCtxt, TypeVisitableExt, + self, AdtDef, CoroutineArgsExt, EarlyBinder, PseudoCanonicalInput, Ty, TyCtxt, + TypeVisitableExt, Unnormalized, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::{Symbol, sym}; @@ -51,7 +52,7 @@ fn layout_of<'tcx>( // One that can be called after typecheck has completed and can use // `normalize_erasing_regions` here and another one that can be called // before typecheck has completed and uses `try_normalize_erasing_regions`. - let ty = match tcx.try_normalize_erasing_regions(typing_env, ty) { + let ty = match tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) { Ok(t) => t, Err(normalization_error) => { return Err(tcx @@ -419,9 +420,10 @@ fn layout_of_uncached<'tcx>( let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); - let metadata_ty = match tcx - .try_normalize_erasing_regions(cx.typing_env, pointee_metadata) - { + let metadata_ty = match tcx.try_normalize_erasing_regions( + cx.typing_env, + Unnormalized::new_wip(pointee_metadata), + ) { Ok(metadata_ty) => metadata_ty, Err(mut err) => { // Usually `::Metadata` can't be normalized because @@ -434,7 +436,12 @@ fn layout_of_uncached<'tcx>( // error. match tcx.try_normalize_erasing_regions( cx.typing_env, - tcx.struct_tail_raw(pointee, &ObligationCause::dummy(), |ty| ty, || {}), + Unnormalized::new_wip(tcx.struct_tail_raw( + pointee, + &ObligationCause::dummy(), + |ty| ty, + || {}, + )), ) { Ok(_) => {} Err(better_err) => { @@ -521,7 +528,8 @@ fn layout_of_uncached<'tcx>( .iter() .map(|local| { let field_ty = EarlyBinder::bind(local.ty); - let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args)); + let uninit_ty = + Ty::new_maybe_uninit(tcx, field_ty.instantiate(tcx, args).skip_norm_wip()); cx.spanned_layout_of(uninit_ty, local.source_info.span) }) .try_collect::>()?; @@ -679,7 +687,10 @@ fn layout_of_uncached<'tcx>( let maybe_unsized = def.is_struct() && def.non_enum_variant().tail_opt().is_some_and(|last_field| { let typing_env = ty::TypingEnv::post_analysis(tcx, def.did()); - !tcx.type_of(last_field.did).instantiate_identity().is_sized(tcx, typing_env) + !tcx.type_of(last_field.did) + .instantiate_identity() + .skip_norm_wip() + .is_sized(tcx, typing_env) }); let layout = cx diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 2cff60de9d1cf..89c526bf8d70a 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -7,7 +7,7 @@ use rustc_hir::limit::Limit; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components}; -use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt, Unnormalized}; use tracing::{debug, instrument}; use crate::errors::NeedsDropOverflow; @@ -211,7 +211,9 @@ where for field_ty in &witness.field_tys { queue_type( self, - EarlyBinder::bind(field_ty.ty).instantiate(tcx, args), + EarlyBinder::bind(field_ty.ty) + .instantiate(tcx, args) + .skip_norm_wip(), ); } } @@ -254,7 +256,10 @@ where }; for required_ty in tys { let required = tcx - .try_normalize_erasing_regions(self.typing_env, required_ty) + .try_normalize_erasing_regions( + self.typing_env, + Unnormalized::new_wip(required_ty), + ) .unwrap_or(required_ty); queue_type(self, required); @@ -335,7 +340,7 @@ fn drop_tys_helper<'tcx>( match subty.kind() { ty::Adt(adt_id, args) => { for subty in tcx.adt_drop_tys(adt_id.did())? { - vec.push(EarlyBinder::bind(subty).instantiate(tcx, args)); + vec.push(EarlyBinder::bind(subty).instantiate(tcx, args).skip_norm_wip()); } } _ => vec.push(subty), @@ -368,7 +373,7 @@ fn drop_tys_helper<'tcx>( Ok(Vec::new()) } else { let field_tys = adt_def.all_fields().map(|field| { - let r = tcx.type_of(field.did).instantiate(tcx, args); + let r = tcx.type_of(field.did).instantiate(tcx, args).skip_norm_wip(); debug!( "drop_tys_helper: Instantiate into {:?} with {:?} getting {:?}", field, args, r @@ -425,7 +430,7 @@ fn adt_drop_tys<'tcx>( // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_args)` drop_tys_helper( tcx, - tcx.type_of(def_id).instantiate_identity(), + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), ty::TypingEnv::non_body_analysis(tcx, def_id), adt_has_dtor, false, @@ -445,7 +450,7 @@ fn adt_async_drop_tys<'tcx>( // `tcx.type_of(def_id)` identical to `tcx.make_adt(def, identity_args)` drop_tys_helper( tcx, - tcx.type_of(def_id).instantiate_identity(), + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), ty::TypingEnv::non_body_analysis(tcx, def_id), adt_has_dtor, false, @@ -464,7 +469,7 @@ fn adt_significant_drop_tys( ) -> Result<&ty::List>, AlwaysRequiresDrop> { drop_tys_helper( tcx, - tcx.type_of(def_id).instantiate_identity(), // identical to `tcx.make_adt(def, identity_args)` + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), // identical to `tcx.make_adt(def, identity_args)` ty::TypingEnv::non_body_analysis(tcx, def_id), adt_consider_insignificant_dtor(tcx), true, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index f27ab51278d3e..09bc62abbaa1d 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -5,7 +5,9 @@ use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_middle::query::Providers; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Unnormalized, +}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; use tracing::{instrument, trace}; @@ -140,8 +142,11 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { // Collect opaque types nested within the associated type bounds of this opaque type. // We use identity args here, because we already know that the opaque type uses // only generic parameters, and thus instantiating would not give us more information. - for (pred, span) in - self.tcx.explicit_item_bounds(alias_ty.kind.def_id()).iter_identity_copied() + for (pred, span) in self + .tcx + .explicit_item_bounds(alias_ty.kind.def_id()) + .iter_identity_copied() + .map(Unnormalized::skip_norm_wip) { trace!(?pred); self.visit_spanned(span, pred); @@ -216,7 +221,11 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { if !self.seen.insert(def_id) { return; } - self.tcx.type_of(def_id).instantiate(self.tcx, args).visit_with(self); + self.tcx + .type_of(def_id) + .instantiate(self.tcx, args) + .skip_norm_wip() + .visit_with(self); } ty::Alias( alias_ty @ ty::AliasTy { kind: ty::Projection { def_id: alias_def_id }, .. }, @@ -225,7 +234,8 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // supporting the case of a method defining opaque types from assoc types // in the same impl block. if let Some(parent) = self.tcx.trait_impl_of_assoc(self.item.to_def_id()) { - let impl_trait_ref = self.tcx.impl_trait_ref(parent).instantiate_identity(); + let impl_trait_ref = + self.tcx.impl_trait_ref(parent).instantiate_identity().skip_norm_wip(); // If the trait ref of the associated item and the impl differs, // then we can't use the impl's identity args below, so // just skip. @@ -256,6 +266,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { self.tcx .type_of(assoc.def_id) .instantiate(self.tcx, alias_args) + .skip_norm_wip() .visit_with(self); return; } else { @@ -281,7 +292,11 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { // `Projection(::synthetic_assoc_ty, trait_def::opaque)` // assumption to the `param_env` of the default method. We also separately // rely on that assumption here. - let ty = self.tcx.type_of(alias_def_id).instantiate(self.tcx, alias_ty.args); + let ty = self + .tcx + .type_of(alias_def_id) + .instantiate(self.tcx, alias_ty.args) + .skip_norm_wip(); let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { .. }, .. }) = *ty.kind() else { diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index c83e0bb77fcfc..6b147b383eb0a 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -24,7 +24,10 @@ fn check_representability(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } DefKind::Field => { - check_representability_ty(tcx, tcx.type_of(def_id).instantiate_identity()); + check_representability_ty( + tcx, + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), + ); } def_kind => bug!("unexpected {def_kind:?}"), } @@ -91,7 +94,7 @@ fn params_in_repr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DenseBitSet { for field in variant.fields.iter() { params_in_repr_ty( tcx, - tcx.type_of(field.did).instantiate_identity(), + tcx.type_of(field.did).instantiate_identity().skip_norm_wip(), &mut params_in_repr, ); } diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 796aa2093bd5f..ab4bfd998cf34 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -4,7 +4,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable, VisitorResult, try_visit}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitable, Unnormalized, VisitorResult, try_visit}; use rustc_span::Span; use tracing::{instrument, trace}; @@ -31,14 +31,14 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( if hir_sig.output.is_suggestable_infer_ty().is_some() { return V::Result::output(); } - let ty_sig = tcx.fn_sig(item).instantiate_identity(); + let ty_sig = tcx.fn_sig(item).instantiate_identity().skip_norm_wip(); // Walk over the inputs and outputs manually in order to get good spans for them. try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output())); for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) { try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x))); } for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { - try_visit!(visitor.visit(span, pred)); + try_visit!(visitor.visit(span, pred.skip_norm_wip())); } } // Walk over the type behind the alias @@ -53,21 +53,21 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( return V::Result::output(); } // Associated types in traits don't necessarily have a type that we can visit - try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity())); + try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity().skip_norm_wip())); } for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { - try_visit!(visitor.visit(span, pred)); + try_visit!(visitor.visit(span, pred.skip_norm_wip())); } } DefKind::OpaqueTy => { - for (pred, span) in tcx.explicit_item_bounds(item).iter_identity_copied() { + for (pred, span) in tcx.explicit_item_bounds(item).iter_identity_copied().map(Unnormalized::skip_norm_wip) { try_visit!(visitor.visit(span, pred)); } } // Look at field types DefKind::Struct | DefKind::Union | DefKind::Enum => { let span = tcx.def_ident_span(item).unwrap(); - let ty = tcx.type_of(item).instantiate_identity(); + let ty = tcx.type_of(item).instantiate_identity().skip_norm_wip(); try_visit!(visitor.visit(span, ty)); let ty::Adt(def, args) = ty.kind() else { span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind()) @@ -78,7 +78,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( try_visit!(visitor.visit(span, ty)); } for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { - try_visit!(visitor.visit(span, pred)); + try_visit!(visitor.visit(span, pred.skip_norm_wip())); } } // These are not part of a public API, they can only appear as hidden types, and there @@ -88,21 +88,21 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( DefKind::Impl { of_trait } => { if of_trait { let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().trait_ref.path.span; - let args = &tcx.impl_trait_ref(item).instantiate_identity().args[1..]; + let args = &tcx.impl_trait_ref(item).instantiate_identity().skip_norm_wip().args[1..]; try_visit!(visitor.visit(span, args)); } let span = match tcx.hir_node_by_def_id(item).ty() { Some(ty) => ty.span, _ => tcx.def_span(item), }; - try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity())); + try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity().skip_norm_wip())); for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { - try_visit!(visitor.visit(span, pred)); + try_visit!(visitor.visit(span, pred.skip_norm_wip())); } } DefKind::TraitAlias | DefKind::Trait => { for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { - try_visit!(visitor.visit(span, pred)); + try_visit!(visitor.visit(span, pred.skip_norm_wip())); } } | DefKind::Variant diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 77d23060ba9e4..00145b6f60d23 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,8 +6,8 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, - fold_regions, + self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Unnormalized, + Upcast, fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; @@ -68,7 +68,7 @@ fn sizedness_constraint_for_ty<'tcx>( } ty::Adt(adt, args) => adt.sizedness_constraint(tcx, sizedness).and_then(|intermediate| { - let ty = intermediate.instantiate(tcx, args); + let ty = intermediate.instantiate(tcx, args).skip_norm_wip(); sizedness_constraint_for_ty(tcx, sizedness, ty) }), @@ -127,7 +127,7 @@ fn adt_sizedness_constraint<'tcx>( } let tail_def = def.non_enum_variant().tail_opt()?; - let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); + let tail_ty = tcx.type_of(tail_def.did).instantiate_identity().skip_norm_wip(); let constraint_ty = sizedness_constraint_for_ty(tcx, sizedness, tail_ty)?; @@ -150,8 +150,9 @@ fn adt_sizedness_constraint<'tcx>( /// See `ParamEnv` struct definition for details. fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // Compute the bounds on Self and the type parameters. - let ty::InstantiatedPredicates { mut predicates, .. } = + let ty::InstantiatedPredicates { predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); + let mut predicates: Vec<_> = predicates.into_iter().map(Unnormalized::skip_norm_wip).collect(); // Finally, we have to normalize the bounds in the environment, in // case they contain any associated type projections. This process @@ -170,7 +171,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { && assoc_item.container == ty::AssocContainer::Trait && assoc_item.defaultness(tcx).has_value() { - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); // We accounted for the binder of the fn sig, so skip the binder. sig.skip_binder().visit_with(&mut ImplTraitInTraitFinder { tcx, @@ -185,11 +186,12 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // We extend the param-env of our item with the const conditions of the item, // since we're allowed to assume `[const]` bounds hold within the item itself. if tcx.is_conditionally_const(def_id) { - predicates.extend( - tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map( - |(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe), - ), - ); + predicates.extend(tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map( + |(trait_ref, _)| { + let trait_ref = trait_ref.skip_norm_wip(); + trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) + }, + )); } let local_did = def_id.as_local(); @@ -259,7 +261,8 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { let default_ty = self .tcx .type_of(shifted_alias_ty.kind.def_id()) - .instantiate(self.tcx, shifted_alias_ty.args); + .instantiate(self.tcx, shifted_alias_ty.args) + .skip_norm_wip(); self.predicates.push( ty::Binder::bind_with_vars( @@ -280,6 +283,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { .tcx .item_bounds(unshifted_alias_ty_def_id) .iter_instantiated(self.tcx, unshifted_alias_ty.args) + .map(Unnormalized::skip_norm_wip) { bound.visit_with(self); } @@ -327,7 +331,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe }; let mut unsizing_params = DenseBitSet::new_empty(num_params); - for arg in tcx.type_of(tail_field.did).instantiate_identity().walk() { + for arg in tcx.type_of(tail_field.did).instantiate_identity().skip_norm_wip().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); } @@ -336,7 +340,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> DenseBitSe // Ensure none of the other fields mention the parameters used // in unsizing. for field in prefix_fields { - for arg in tcx.type_of(field.did).instantiate_identity().walk() { + for arg in tcx.type_of(field.did).instantiate_identity().skip_norm_wip().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } @@ -356,16 +360,17 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) let param_env = tcx.param_env(impl_def_id); let tail = tcx.struct_tail_raw( - tcx.type_of(impl_def_id).instantiate_identity(), + tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip(), &cause, |ty| { - ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| { - Ty::new_error_with_message( - tcx, - tcx.def_span(impl_def_id), - "struct tail should be computable", - ) - }) + ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty)) + .unwrap_or_else(|_| { + Ty::new_error_with_message( + tcx, + tcx.def_span(impl_def_id), + "struct tail should be computable", + ) + }) }, || (), ); diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 76140e6a762fe..a005325ea18d4 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -16,7 +16,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex}; +use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex, Unnormalized}; /// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -459,8 +459,8 @@ where /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), /// but on an iterator of `TypeFoldable` values. - pub fn iter_identity(self) -> Iter::IntoIter { - self.value.into_iter() + pub fn iter_identity(self) -> impl Iterator> { + self.value.into_iter().map(Unnormalized::new) } } @@ -475,7 +475,7 @@ where Iter::Item: TypeFoldable, A: SliceLike, { - type Item = Iter::Item; + type Item = Unnormalized; fn next(&mut self) -> Option { Some( @@ -526,8 +526,8 @@ where /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), /// but on an iterator of values that deref to a `TypeFoldable`. - pub fn iter_identity_copied(self) -> IterIdentityCopied { - IterIdentityCopied { it: self.value.into_iter() } + pub fn iter_identity_copied(self) -> IterIdentityCopied { + IterIdentityCopied { it: self.value.into_iter(), _tcx: PhantomData } } } @@ -542,7 +542,7 @@ where Iter::Item: Deref, ::Target: Copy + TypeFoldable, { - type Item = ::Target; + type Item = Unnormalized::Target>; fn next(&mut self) -> Option { self.it.next().map(|value| { @@ -576,19 +576,20 @@ where { } -pub struct IterIdentityCopied { +pub struct IterIdentityCopied { it: Iter::IntoIter, + _tcx: PhantomData I>, } -impl Iterator for IterIdentityCopied +impl Iterator for IterIdentityCopied where Iter::Item: Deref, ::Target: Copy, { - type Item = ::Target; + type Item = Unnormalized::Target>; fn next(&mut self) -> Option { - self.it.next().map(|i| *i) + self.it.next().map(|i| Unnormalized::new(*i)) } fn size_hint(&self) -> (usize, Option) { @@ -596,18 +597,18 @@ where } } -impl DoubleEndedIterator for IterIdentityCopied +impl DoubleEndedIterator for IterIdentityCopied where Iter::IntoIter: DoubleEndedIterator, Iter::Item: Deref, ::Target: Copy, { fn next_back(&mut self) -> Option { - self.it.next_back().map(|i| *i) + self.it.next_back().map(|i| Unnormalized::new(*i)) } } -impl ExactSizeIterator for IterIdentityCopied +impl ExactSizeIterator for IterIdentityCopied where Iter::IntoIter: ExactSizeIterator, Iter::Item: Deref, @@ -638,7 +639,7 @@ impl Iterator for EarlyBinderIter { } impl> ty::EarlyBinder { - pub fn instantiate(self, cx: I, args: A) -> T + pub fn instantiate(self, cx: I, args: A) -> Unnormalized where A: SliceLike, { @@ -651,10 +652,10 @@ impl> ty::EarlyBinder { "{:?} has parameters, but no args were provided in instantiate", self.value, ); - return self.value; + return Unnormalized::new(self.value); } let mut folder = ArgFolder { cx, args: args.as_slice(), binders_passed: 0 }; - self.value.fold_with(&mut folder) + Unnormalized::new(self.value.fold_with(&mut folder)) } /// Makes the identity replacement `T0 => T0, ..., TN => TN`. @@ -665,8 +666,8 @@ impl> ty::EarlyBinder { /// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`). /// - Inside of the body of `foo`, we treat `T` as a placeholder by calling /// `instantiate_identity` to discharge the `EarlyBinder`. - pub fn instantiate_identity(self) -> T { - self.value + pub fn instantiate_identity(self) -> Unnormalized { + Unnormalized::new(self.value) } /// Returns the inner value, but only if it contains no bound vars. diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 2f7c78d497a4f..f8075f2927d8b 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -6,7 +6,7 @@ use crate::data_structures::HashSet; use crate::inherent::*; use crate::lang_items::SolverTraitLangItem; use crate::outlives::{Component, push_outlives_components}; -use crate::{self as ty, Interner, Upcast as _}; +use crate::{self as ty, Interner, Unnormalized, Upcast as _}; /// "Elaboration" is the process of identifying all the predicates that /// are implied by a source predicate. Currently, this basically means @@ -168,12 +168,14 @@ impl> Elaborator { Filter::All => self.extend_deduped( cx.explicit_implied_predicates_of(data.def_id().into()) .iter_identity() + .map(Unnormalized::skip_norm_wip) .enumerate() .map(map_to_child_clause), ), Filter::OnlySelf => self.extend_deduped( cx.explicit_super_predicates_of(data.def_id()) .iter_identity() + .map(Unnormalized::skip_norm_wip) .enumerate() .map(map_to_child_clause), ), @@ -181,15 +183,16 @@ impl> Elaborator { } // `T: [const] Trait` implies `T: [const] Supertrait`. ty::ClauseKind::HostEffect(data) => self.extend_deduped( - cx.explicit_implied_const_bounds(data.def_id().into()).iter_identity().map( - |trait_ref| { + cx.explicit_implied_const_bounds(data.def_id().into()) + .iter_identity() + .map(Unnormalized::skip_norm_wip) + .map(|trait_ref| { elaboratable.child( trait_ref .to_host_effect_clause(cx, data.constness) .instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)), ) - }, - ), + }), ), ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => { // We know that `T: 'a` for some type `T`. We can @@ -324,7 +327,11 @@ pub fn supertrait_def_ids( std::iter::from_fn(move || { let trait_def_id = stack.pop()?; - for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() { + for (predicate, _) in cx + .explicit_super_predicates_of(trait_def_id) + .iter_identity() + .map(Unnormalized::skip_norm_wip) + { if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() && set.insert(data.def_id()) { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a0b444024ca79..8f314ab86da24 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -53,6 +53,7 @@ mod predicate_kind; mod region_kind; mod ty_info; mod ty_kind; +mod unnormalized; mod upcast; mod visit; @@ -80,6 +81,7 @@ pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintT use rustc_type_ir_macros::GenericTypeVisitable; pub use ty_info::*; pub use ty_kind::*; +pub use unnormalized::Unnormalized; pub use upcast::*; pub use visit::*; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 61095a00d0414..48fa1e59f4587 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -593,8 +593,8 @@ pub fn structurally_relate_consts>( (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { // FIXME(mgca): remove this if cfg!(debug_assertions) { - let a_ty = cx.type_of(au.def.into()).instantiate(cx, au.args); - let b_ty = cx.type_of(bu.def.into()).instantiate(cx, bu.args); + let a_ty = cx.type_of(au.def.into()).instantiate(cx, au.args).skip_norm_wip(); + let b_ty = cx.type_of(bu.def.into()).instantiate(cx, bu.args).skip_norm_wip(); assert_eq!(a_ty, b_ty); } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 9c57d04159cc8..d0dbe71ac6145 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -305,7 +305,9 @@ impl TyKind { pub fn fn_sig(self, interner: I) -> ty::Binder> { match self { ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr), - ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args), + ty::FnDef(def_id, args) => { + interner.fn_sig(def_id).instantiate(interner, args).skip_norm_wip() + } ty::Error(_) => { // ignore errors (#54954) ty::Binder::dummy(ty::FnSig { diff --git a/compiler/rustc_type_ir/src/unnormalized.rs b/compiler/rustc_type_ir/src/unnormalized.rs new file mode 100644 index 0000000000000..5857a89928e7d --- /dev/null +++ b/compiler/rustc_type_ir/src/unnormalized.rs @@ -0,0 +1,105 @@ +use std::marker::PhantomData; + +use derive_where::derive_where; + +use crate::inherent::*; +use crate::{Binder, Interner, PredicatePolarity, TraitPredicate}; + +/// A wrapper for value that needs normalization. +/// FIXME: This is very WIP. The plan is to replace the `skip_norm_wip` spread +/// throughout the codebase with proper normalization. This is the first step toward +/// switching to eager normalization with the next solver. +/// +/// The interner type parameter exists to constraint generic for certain impl, e.g., +/// `Unnormalized`. +#[derive_where(Clone, Copy, PartialOrd, PartialEq, Debug; T)] +pub struct Unnormalized { + value: T, + #[derive_where(skip(Debug))] + _tcx: PhantomData I>, +} + +impl Unnormalized { + /// Should only be used in limited situations where you produce an potentially + /// unnormalized value, like in (Early)Binder/GenericPredicates instantiation. + pub fn new(value: T) -> Unnormalized { + Unnormalized { value, _tcx: PhantomData } + } + + /// FIXME: This is going to be eventually removed once we migrate the relevant + /// APIs to return `Unnormalized`. + pub fn new_wip(value: T) -> Unnormalized { + Unnormalized { value, _tcx: PhantomData } + } + + /// Intentionally skip normalization. + /// You probably should perform normalization in most cases. + pub fn skip_normalization(self) -> T { + self.value + } + + /// FIXME: This is going to be eventually removed. + /// If you meet this in codebase, try using one of the normalization routines + /// to consume the `Unnormalized` wrapper. Or use `skip_normalization` when normalization + /// is really unnecessary. + pub fn skip_norm_wip(self) -> T { + self.value + } + + /// FIXME: Should I just use `skip_normalization`? + /// Kinda weird to call that insides normalization methods. + pub fn inside_norm(self) -> T { + self.value + } + + pub fn probe(&self, f: F) -> U + where + F: FnOnce(&T) -> U, + { + f(&self.value) + } + + pub fn map_inner(self, f: F) -> Unnormalized + where + F: FnOnce(T) -> U, + { + Unnormalized { value: f(self.value), _tcx: PhantomData } + } + + pub fn as_ref(&self) -> Unnormalized { + Unnormalized { value: &self.value, _tcx: PhantomData } + } +} + +impl Unnormalized { + pub fn unzip(self) -> (Unnormalized, Unnormalized) { + (Unnormalized::new(self.value.0), Unnormalized::new(self.value.1)) + } +} + +impl Unnormalized> { + pub fn skip_binder(self) -> T { + self.value.skip_binder() + } +} + +impl Unnormalized { + pub fn as_trait_clause(self) -> Option>>> { + self.value.as_trait_clause().map(|v| Unnormalized::new(v)) + } +} + +impl Unnormalized>> { + pub fn self_ty(self) -> Unnormalized> { + self.map_inner(|pred| pred.self_ty()) + } + + pub fn def_id(self) -> I::TraitId { + self.value.skip_binder().def_id() + } + + #[inline] + pub fn polarity(self) -> PredicatePolarity { + self.value.skip_binder().polarity + } +} diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fc61103d939fb..3a0eeeead9727 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -22,7 +22,7 @@ pub(crate) fn synthesize_auto_trait_impls<'tcx>( ) -> Vec { let tcx = cx.tcx; let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id); - let ty = tcx.type_of(item_def_id).instantiate_identity(); + let ty = tcx.type_of(item_def_id).instantiate_identity().skip_norm_wip(); let finder = auto_trait::AutoTraitFinder::new(tcx); let mut auto_trait_impls: Vec<_> = cx diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index de45922e856f7..8dda831cac85b 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -2,7 +2,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt}; use rustc_infer::traits; -use rustc_middle::ty::{self, TypingMode, Upcast}; +use rustc_middle::ty::{self, TypingMode, Unnormalized, Upcast}; use rustc_span::DUMMY_SP; use rustc_span::def_id::DefId; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -40,11 +40,11 @@ pub(crate) fn synthesize_blanket_impls( } let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id); - let impl_ty = ty.instantiate(tcx, args); + let impl_ty = ty.instantiate(tcx, args).skip_norm_wip(); let param_env = ty::ParamEnv::empty(); let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = trait_ref.instantiate(tcx, impl_args); + let impl_trait_ref = trait_ref.instantiate(tcx, impl_args).skip_norm_wip(); // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. @@ -64,6 +64,7 @@ pub(crate) fn synthesize_blanket_impls( .instantiate(tcx, impl_args) .predicates .into_iter() + .map(Unnormalized::skip_norm_wip) .chain(Some(impl_trait_ref.upcast(tcx))); for predicate in predicates { let obligation = traits::Obligation::new( @@ -95,11 +96,11 @@ pub(crate) fn synthesize_blanket_impls( // the post-inference `trait_ref`, as it's more accurate. trait_: Some(clean_trait_ref_with_constraints( cx, - ty::Binder::dummy(trait_ref.instantiate_identity()), + ty::Binder::dummy(trait_ref.instantiate_identity().skip_norm_wip()), ThinVec::new(), )), for_: clean_middle_ty( - ty::Binder::dummy(ty.instantiate_identity()), + ty::Binder::dummy(ty.instantiate_identity().skip_norm_wip()), cx, None, None, @@ -112,7 +113,9 @@ pub(crate) fn synthesize_blanket_impls( .collect(), polarity: ty::ImplPolarity::Positive, kind: clean::ImplKind::Blanket(Box::new(clean_middle_ty( - ty::Binder::dummy(trait_ref.instantiate_identity().self_ty()), + ty::Binder::dummy( + trait_ref.instantiate_identity().skip_norm_wip().self_ty(), + ), cx, None, None, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 1451b6db8095d..3ca22b0360b9c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -309,7 +309,7 @@ fn build_trait_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::TraitAlias { } pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); // The generics need to be cleaned before the signature. let mut generics = clean_ty_generics(cx, def_id); let bound_vars = clean_bound_vars(sig.bound_vars(), cx.tcx); @@ -369,7 +369,7 @@ fn build_type_alias( did: DefId, ret: &mut Vec, ) -> Box { - let ty = cx.tcx.type_of(did).instantiate_identity(); + let ty = cx.tcx.type_of(did).instantiate_identity().skip_norm_wip(); let type_ = clean_middle_ty(ty::Binder::dummy(ty), cx, Some(did), None); let inner_type = clean_ty_alias_inner_type(ty, cx, ret); @@ -488,7 +488,7 @@ pub(crate) fn build_impl( let for_ = match &impl_item { Some(impl_) => clean_ty(impl_.self_ty, cx), None => clean_middle_ty( - ty::Binder::dummy(tcx.type_of(did).instantiate_identity()), + ty::Binder::dummy(tcx.type_of(did).instantiate_identity().skip_norm_wip()), cx, Some(did), None, @@ -749,7 +749,7 @@ fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { let mut generics = clean_ty_generics(cx, def_id); clean::simplify::move_bounds_to_generic_parameters(&mut generics); let ty = clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), + ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()), cx, None, None, @@ -760,7 +760,7 @@ fn build_const_item(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { type_: Box::new(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()), + ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity().skip_norm_wip()), cx, Some(did), None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5fa5c7b0519ac..07a2b147278d2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -46,7 +46,9 @@ use rustc_hir::{LangItem, PredicateOrigin, find_attr}; use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty}; use rustc_middle::metadata::Reexport; use rustc_middle::middle::resolve_bound_vars as rbv; -use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{ + self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, +}; use rustc_middle::{bug, span_bug}; use rustc_span::ExpnKind; use rustc_span::hygiene::{AstPass, MacroKind}; @@ -507,7 +509,7 @@ fn clean_hir_term<'tcx>( hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)), hir::Term::Const(c) => { // FIXME(generic_const_items): this should instantiate with the alias item's args - let ty = cx.tcx.type_of(assoc_item.unwrap()).instantiate_identity(); + let ty = cx.tcx.type_of(assoc_item.unwrap()).instantiate_identity().skip_norm_wip(); let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty); Term::Constant(clean_middle_const(ty::Binder::dummy(ct))) } @@ -590,7 +592,9 @@ fn clean_generic_param_def( && has_default { Some(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def.def_id).instantiate_identity()), + ty::Binder::dummy( + cx.tcx.type_of(def.def_id).instantiate_identity().skip_norm_wip(), + ), cx, Some(def.def_id), None, @@ -611,7 +615,9 @@ fn clean_generic_param_def( def.name, GenericParamDefKind::Const { ty: Box::new(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def.def_id).instantiate_identity()), + ty::Binder::dummy( + cx.tcx.type_of(def.def_id).instantiate_identity().skip_norm_wip(), + ), cx, Some(def.def_id), None, @@ -620,7 +626,11 @@ fn clean_generic_param_def( && has_default { Some(Box::new( - cx.tcx.const_param_default(def.def_id).instantiate_identity().to_string(), + cx.tcx + .const_param_default(def.def_id) + .instantiate_identity() + .skip_norm_wip() + .to_string(), )) } else { None @@ -1328,7 +1338,9 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo let kind = match assoc_item.kind { ty::AssocKind::Const { .. } => { let ty = clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()), + ty::Binder::dummy( + tcx.type_of(assoc_item.def_id).instantiate_identity().skip_norm_wip(), + ), cx, Some(assoc_item.def_id), None, @@ -1363,13 +1375,18 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo if has_self { let self_ty = match assoc_item.container { - ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { - tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity() - } + ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => tcx + .type_of(assoc_item.container_id(tcx)) + .instantiate_identity() + .skip_norm_wip(), ty::AssocContainer::Trait => tcx.types.self_param, }; - let self_param_ty = - tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder(); + let self_param_ty = tcx + .fn_sig(assoc_item.def_id) + .instantiate_identity() + .skip_norm_wip() + .input(0) + .skip_binder(); if self_param_ty == self_ty { item.decl.inputs[0].type_ = SelfTy; } else if let ty::Ref(_, ty, _) = *self_param_ty.kind() @@ -1423,7 +1440,10 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; if let ty::AssocContainer::Trait = assoc_item.container { - let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied(); + let bounds = tcx + .explicit_item_bounds(assoc_item.def_id) + .iter_identity_copied() + .map(Unnormalized::skip_normalization); predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); } let mut generics = clean_ty_generics_inner( @@ -1509,7 +1529,9 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo Box::new(TypeAlias { type_: clean_middle_ty( ty::Binder::dummy( - tcx.type_of(assoc_item.def_id).instantiate_identity(), + tcx.type_of(assoc_item.def_id) + .instantiate_identity() + .skip_norm_wip(), ), cx, Some(assoc_item.def_id), @@ -1529,7 +1551,9 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo Box::new(TypeAlias { type_: clean_middle_ty( ty::Binder::dummy( - tcx.type_of(assoc_item.def_id).instantiate_identity(), + tcx.type_of(assoc_item.def_id) + .instantiate_identity() + .skip_norm_wip(), ), cx, Some(assoc_item.def_id), @@ -1868,7 +1892,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); - let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); + let ct = cx.tcx.normalize_erasing_regions(typing_env, Unnormalized::new(ct)); print_const(cx.tcx, ct) } hir::ConstArgKind::Struct(..) @@ -2097,7 +2121,7 @@ pub(crate) fn clean_middle_ty<'tcx>( format!("{pat:?}").into_boxed_str(), ), ty::Array(ty, n) => { - let n = cx.tcx.normalize_erasing_regions(cx.typing_env(), n); + let n = cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new(n)); let n = print_const(cx.tcx, n); Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), n.into()) } @@ -2267,7 +2291,7 @@ pub(crate) fn clean_middle_ty<'tcx>( clean_middle_path(cx, def_id, false, ThinVec::new(), bound_ty.rebind(args)); Type::Path { path } } else { - let ty = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); + let ty = cx.tcx.type_of(def_id).instantiate(cx.tcx, args).skip_norm_wip(); clean_middle_ty(bound_ty.rebind(ty), cx, None, None) } } @@ -2330,6 +2354,7 @@ fn clean_middle_opaque_bounds<'tcx>( .tcx .explicit_item_bounds(impl_trait_def_id) .iter_instantiated_copied(cx.tcx, args) + .map(Unnormalized::skip_normalization) .collect(); let mut bounds = bounds @@ -2427,7 +2452,7 @@ pub(crate) fn clean_middle_field(field: &ty::FieldDef, cx: &mut DocContext<'_>) field.did, field.name, clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(field.did).instantiate_identity()), + ty::Binder::dummy(cx.tcx.type_of(field.did).instantiate_identity().skip_norm_wip()), cx, Some(field.did), None, @@ -2491,7 +2516,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( .fields .iter() .map(|field| { - let ty = cx.tcx.type_of(field.did).instantiate(cx.tcx, args); + let ty = cx.tcx.type_of(field.did).instantiate(cx.tcx, args).skip_norm_wip(); // normalize the type to only show concrete types // note: we do not use try_normalize_erasing_regions since we @@ -2516,7 +2541,7 @@ pub(crate) fn clean_variant_def_with_args<'tcx>( .fields .iter() .map(|field| { - let ty = cx.tcx.type_of(field.did).instantiate(cx.tcx, args); + let ty = cx.tcx.type_of(field.did).instantiate(cx.tcx, args).skip_norm_wip(); // normalize the type to only show concrete types // note: we do not use try_normalize_erasing_regions since we @@ -2860,7 +2885,7 @@ fn clean_maybe_renamed_item<'tcx>( } } - let ty = cx.tcx.type_of(def_id).instantiate_identity(); + let ty = cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); let mut ret = Vec::new(); let inner_type = clean_ty_alias_inner_type(ty, cx, &mut ret); @@ -2993,7 +3018,7 @@ fn clean_impl<'tcx>( let type_alias = for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) { DefKind::TyAlias => Some(clean_middle_ty( - ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()), + ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity().skip_norm_wip()), cx, Some(def_id.to_def_id()), None, diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 154f31e89dbff..518f850adbd2d 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::DefId; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{TyCtxt, Unnormalized}; use crate::clean; use crate::clean::{GenericArgs as PP, WherePredicate as WP}; @@ -116,6 +116,7 @@ fn trait_is_same_or_supertrait(tcx: TyCtxt<'_>, child: DefId, trait_: DefId) -> let predicates = tcx.explicit_super_predicates_of(child); predicates .iter_identity_copied() + .map(Unnormalized::skip_normalization) .filter_map(|(pred, _)| Some(pred.as_trait_clause()?.def_id())) .any(|did| trait_is_same_or_supertrait(tcx, did, trait_)) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 2284b815a09a9..ecf20dd9754ae 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -126,7 +126,7 @@ pub(crate) fn clean_middle_generic_args<'tcx>( // Elide arguments that coincide with their default. if !elision_has_failed_once_before && let Some(default) = param.default_value(cx.tcx) { - let default = default.instantiate(cx.tcx, args.as_ref()); + let default = default.instantiate(cx.tcx, args.as_ref()).skip_norm_wip(); if can_elide_generic_arg(arg, arg.rebind(default)) { return None; } @@ -371,7 +371,7 @@ pub(crate) fn print_evaluated_const( with_type: bool, ) -> Option { tcx.const_eval_poly(def_id).ok().and_then(|val| { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); match (val, ty.kind()) { (_, &ty::Ref(..)) => None, (mir::ConstValue::Scalar(_), &ty::Adt(_, _)) => None, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 35071f47a182b..2a00da4dd45c8 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -424,8 +424,12 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => { dids.insert(path.def_id()); if let Some(generics) = path.generics() - && let ty::Adt(adt, _) = - self.tcx.type_of(path.def_id()).instantiate_identity().kind() + && let ty::Adt(adt, _) = self + .tcx + .type_of(path.def_id()) + .instantiate_identity() + .skip_norm_wip() + .kind() && adt.is_fundamental() { for ty in generics { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7eff0b5402b48..0694dd05cd399 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -441,7 +441,9 @@ fn generate_item_def_id_path( let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); def_id = infcx .at(&ObligationCause::dummy(), tcx.param_env(def_id)) - .query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity())) + .query_normalize(ty::Binder::dummy( + tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), + )) .map(|resolved| infcx.resolve_vars_if_possible(resolved.value)) .ok() .and_then(|normalized| normalized.skip_binder().ty_adt_def()) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index c0c380447f2cb..a36a3132640c8 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2995,7 +2995,7 @@ fn repr_attribute<'tcx>( // Side note: There can only ever be one or zero non-1-ZST fields. let non_1zst_field = var.fields.iter().find(|field| { let ty = ty::TypingEnv::post_analysis(tcx, field.did) - .as_query_input(tcx.type_of(field.did).instantiate_identity()); + .as_query_input(tcx.type_of(field.did).instantiate_identity().skip_norm_wip()); tcx.layout_of(ty).is_ok_and(|layout| !layout.is_1zst()) }); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5363755a0da7a..48108097864a4 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1275,7 +1275,11 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> match inner_type { clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => { - let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); + let ty = cx + .tcx() + .type_of(it.def_id().unwrap()) + .instantiate_identity() + .skip_norm_wip(); let enum_def_id = ty.ty_adt_def().unwrap().did(); DisplayEnum { @@ -1287,7 +1291,11 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> .render_into(cx, it, true, w)?; } clean::TypeAliasInnerType::Union { fields } => { - let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); + let ty = cx + .tcx() + .type_of(it.def_id().unwrap()) + .instantiate_identity() + .skip_norm_wip(); let union_def_id = ty.ty_adt_def().unwrap().did(); ItemUnion { @@ -1301,7 +1309,11 @@ fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> .render_into(w)?; } clean::TypeAliasInnerType::Struct { ctor_kind, fields } => { - let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity(); + let ty = cx + .tcx() + .type_of(it.def_id().unwrap()) + .instantiate_identity() + .skip_norm_wip(); let struct_def_id = ty.ty_adt_def().unwrap().did(); DisplayStruct { diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 5d5b8d5df685b..e17058c4ca80c 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -32,7 +32,7 @@ pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl f let tcx = cx.tcx(); let typing_env = ty::TypingEnv::post_analysis(tcx, ty_def_id); - let ty = tcx.type_of(ty_def_id).instantiate_identity(); + let ty = tcx.type_of(ty_def_id).instantiate_identity().skip_norm_wip(); let type_layout = tcx.layout_of(typing_env.as_query_input(ty)); let variants = if let Ok(type_layout) = type_layout diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8b66672cfa5ed..45061a02e7525 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -311,7 +311,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { match ty_res { Res::Def(DefKind::Enum | DefKind::TyAlias, did) => { - match tcx.type_of(did).instantiate_identity().kind() { + match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind() { ty::Adt(def, _) if def.is_enum() => { if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) @@ -509,7 +509,9 @@ fn resolve_self_ty<'tcx>( }; match tcx.def_kind(self_id) { - DefKind::Impl { .. } => ty_to_res(tcx, tcx.type_of(self_id).instantiate_identity()), + DefKind::Impl { .. } => { + ty_to_res(tcx, tcx.type_of(self_id).instantiate_identity().skip_norm_wip()) + } DefKind::Use => None, def_kind => Some(Res::Def(def_kind, self_id)), } @@ -606,7 +608,8 @@ fn resolve_associated_item<'tcx>( // Resolve the link on the type the alias points to. // FIXME: if the associated item is defined directly on the type alias, // it will show up on its documentation page, we should link there instead. - let Some(aliased_res) = ty_to_res(tcx, tcx.type_of(alias_did).instantiate_identity()) + let Some(aliased_res) = + ty_to_res(tcx, tcx.type_of(alias_did).instantiate_identity().skip_norm_wip()) else { return vec![]; }; @@ -686,7 +689,7 @@ fn resolve_assoc_on_adt<'tcx>( ) -> Vec<(Res, DefId)> { debug!("looking for associated item named {item_ident} for item {adt_def_id:?}"); let root_res = Res::from_def_id(tcx, adt_def_id); - let adt_ty = tcx.type_of(adt_def_id).instantiate_identity(); + let adt_ty = tcx.type_of(adt_def_id).instantiate_identity().skip_norm_wip(); let adt_def = adt_ty.ty_adt_def().expect("must be ADT"); // Checks if item_name is a variant of the `SomeItem` enum if ns == TypeNS && adt_def.is_enum() { @@ -747,7 +750,7 @@ fn resolve_assoc_on_simple_type<'tcx>( // Although having both would be ambiguous, use impl version for compatibility's sake. // To handle that properly resolve() would have to support // something like [`ambi_fn`](::ambi_fn) - let ty = tcx.type_of(ty_def_id).instantiate_identity(); + let ty = tcx.type_of(ty_def_id).instantiate_identity().skip_norm_wip(); let trait_assoc_items = resolve_associated_trait_item(ty, module_id, item_ident, ns, tcx) .into_iter() .map(|item| (root_res, item.def_id)) @@ -2121,7 +2124,8 @@ fn resolution_failure( Res::Primitive(_) => None, }; let is_struct_variant = |did| { - if let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind() + if let ty::Adt(def, _) = + tcx.type_of(did).instantiate_identity().skip_norm_wip().kind() && def.is_enum() && let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 251efa15e240a..762516874c0ae 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -110,7 +110,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // `Generics`. To avoid relying on the `impl` block, these // things would need to be created from wholecloth, in a // form that is valid for use in type inference. - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); match ty.kind() { ty::Slice(ty) | ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => { matches!(ty.kind(), ty::Param(..)) diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index 63b869c0f2d51..8a7bbf42ff492 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -159,7 +159,7 @@ where }; let ident_span = path.ident.span; - (tcx.type_of(def_id).instantiate_identity(), call_span, ident_span) + (tcx.type_of(def_id).instantiate_identity().skip_norm_wip(), call_span, ident_span) } _ => { return; diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 165941a859f74..8e85ce6171842 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -4,6 +4,7 @@ use clippy_utils::source::walk_span_to_context; use clippy_utils::sugg::Sugg; use clippy_utils::sym; use clippy_utils::ty::{implements_trait, is_copy}; +use rustc_middle::ty::Unnormalized; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Lit}; @@ -64,7 +65,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - }) .is_some_and(|assoc_item| { let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, [])); - let nty = cx.tcx.normalize_erasing_regions(cx.typing_env(), proj); + let nty = cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(proj)); nty.is_bool() }) diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs index 10c97fac992e4..adc43e282fc5c 100644 --- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, && let Some(as_ptr_did) = cx .typeck_results() .type_dependent_def_id(cast_expr.peel_blocks().hir_id) - && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity() + && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity().skip_norm_wip() && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next() && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind() && let Some(recv) = receiver.span.get_source_text(cx) diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index 7d14ba7fcf132..c54dab7e4aec0 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -59,7 +59,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { if matches!(name.ident.name, sym::read_unaligned | sym::write_unaligned) && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.tcx.impl_of_assoc(def_id) - && cx.tcx.type_of(def_id).instantiate_identity().is_raw_ptr() + && cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().is_raw_ptr() { true } else { diff --git a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs index 73347e7141eb4..1dbcfafd6b3d3 100644 --- a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs @@ -38,7 +38,7 @@ fn get_const_name_and_ty_name( return None; } } else if let Some(impl_id) = cx.tcx.impl_of_assoc(method_def_id) - && let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity()) + && let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip()) && matches!( method_name, sym::min | sym::max | sym::minimum | sym::maximum | sym::min_value | sym::max_value diff --git a/src/tools/clippy/clippy_lints/src/casts/needless_type_cast.rs b/src/tools/clippy/clippy_lints/src/casts/needless_type_cast.rs index 1d899a21c229e..844d4c7acbe7f 100644 --- a/src/tools/clippy/clippy_lints/src/casts/needless_type_cast.rs +++ b/src/tools/clippy/clippy_lints/src/casts/needless_type_cast.rs @@ -158,7 +158,7 @@ fn has_generic_return_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { .is_some(), ExprKind::MethodCall(..) => { if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let ret_ty = sig.output().skip_binder(); return ret_ty.has_param(); } @@ -168,7 +168,7 @@ fn has_generic_return_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { if let ExprKind::Path(qpath) = &callee.kind { let res = cx.qpath_res(qpath, callee.hir_id); if let Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) = res { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let ret_ty = sig.output().skip_binder(); return ret_ty.has_param(); } diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs index 51aebd8b0cfba..dff79b2870026 100644 --- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs @@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator { of_trait: Some(of_trait), .. }) = item.kind - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && is_copy(cx, ty) && let Some(trait_id) = of_trait.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Iterator, trait_id) diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 2064d896861ba..2f4a67e15b927 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { .fields .iter() .all(|field| { - is_copy(cx, cx.tcx.type_of(field.did).instantiate(cx.tcx, args)) + is_copy(cx, cx.tcx.type_of(field.did).instantiate(cx.tcx, args).skip_norm_wip()) }) && (!has_drop(cx, binding_type) || all_fields_are_copy) { diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index 1507f1ed30539..4324a8465be6f 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -166,7 +166,7 @@ impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> { ExprKind::MethodCall(_, receiver, args, _) => { if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) { - let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); + let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().skip_binder(); for (expr, bound) in iter::zip(iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) { self.ty_bounds.push((*bound).into()); self.visit_expr(expr); @@ -188,7 +188,7 @@ impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> { for field in *fields { let bound = fields_def.iter().find_map(|f_def| { if f_def.ident(self.cx.tcx) == field.ident { - Some(self.cx.tcx.type_of(f_def.did).instantiate_identity()) + Some(self.cx.tcx.type_of(f_def.did).instantiate_identity().skip_norm_wip()) } else { None } @@ -251,7 +251,7 @@ fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option Some(cx.tcx.fn_sig(*def_id).instantiate_identity()), + ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity().skip_norm_wip()), ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(*hdr)), _ => None, } diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index 61656d6cede51..49d550f1cbd4b 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { /// of that field does not matter either.) fn is_union_with_two_non_zst_fields<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { if let ItemKind::Union(..) = &item.kind - && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() + && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip().kind() { adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2 } else { diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 89a6d445e8180..c152e0fc7f1ac 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -6,6 +6,7 @@ use clippy_utils::ty::{adjust_derefs_manually_drop, implements_trait, is_manuall use clippy_utils::{ DefinedTy, ExprUseNode, expr_use_ctxt, get_parent_expr, is_block_like, is_from_proc_macro, is_lint_allowed, sym, }; +use rustc_middle::ty::Unnormalized; use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; @@ -381,7 +382,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { && let args = typeck.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default() && let impl_ty = - if cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder().inputs()[0] + if cx.tcx.fn_sig(fn_id).instantiate_identity().skip_norm_wip().skip_binder().inputs()[0] .is_ref() { // Trait methods taking `&self` @@ -876,7 +877,7 @@ impl TyCoercionStability { if let Some(def_id) = def_site_def_id { let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); - ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); } loop { break match *ty.kind() { diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index c04163b1c7a07..5e1144254fdb2 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -243,7 +243,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) - && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() + && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip().kind() && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) && cx.tcx.hir_attrs(impl_item_hir).is_empty() diff --git a/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs b/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs index 316d800a70c96..2d7d09285c16d 100644 --- a/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs +++ b/src/tools/clippy/clippy_lints/src/derive/derive_ord_xor_partial_ord.rs @@ -35,7 +35,7 @@ pub(super) fn check<'tcx>( // Only care about `impl PartialOrd for Foo` // For `impl PartialOrd for A, input_types is [A, B] - if trait_ref.instantiate_identity().args.type_at(1) == ty { + if trait_ref.instantiate_identity().skip_norm_wip().args.type_at(1) == ty { let mess = if partial_ord_is_automatically_derived { "you are implementing `Ord` explicitly but have derived `PartialOrd`" } else { diff --git a/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs b/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs index dc3fbe5d7012c..b57a47526b354 100644 --- a/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs +++ b/src/tools/clippy/clippy_lints/src/derive/derived_hash_with_manual_eq.rs @@ -31,7 +31,7 @@ pub(super) fn check<'tcx>( // Only care about `impl PartialEq for Foo` // For `impl PartialEq for A, input_types is [A, B] - if trait_ref.instantiate_identity().args.type_at(1) == ty { + if trait_ref.instantiate_identity().skip_norm_wip().args.type_at(1) == ty { span_lint_hir_and_then( cx, DERIVED_HASH_WITH_MANUAL_EQ, diff --git a/src/tools/clippy/clippy_lints/src/derive/expl_impl_clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/derive/expl_impl_clone_on_copy.rs index b2bc6402561f5..0604a8db46796 100644 --- a/src/tools/clippy/clippy_lints/src/derive/expl_impl_clone_on_copy.rs +++ b/src/tools/clippy/clippy_lints/src/derive/expl_impl_clone_on_copy.rs @@ -32,7 +32,7 @@ pub(super) fn check<'tcx>( if !is_copy(cx, ty) { if ty_subs.non_erasable_generics().next().is_some() { let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| { - matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _) + matches!(cx.tcx.type_of(id).instantiate_identity().skip_norm_wip().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did()) }); if !has_copy_impl { diff --git a/src/tools/clippy/clippy_lints/src/derive/mod.rs b/src/tools/clippy/clippy_lints/src/derive/mod.rs index fa1a7037154eb..d6f928d738cbd 100644 --- a/src/tools/clippy/clippy_lints/src/derive/mod.rs +++ b/src/tools/clippy/clippy_lints/src/derive/mod.rs @@ -204,7 +204,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { { let adt_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id); let trait_ref = &of_trait.trait_ref; - let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); let is_automatically_derived = cx.tcx.is_automatically_derived(item.owner_id.to_def_id()); derived_hash_with_manual_eq::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived); diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs index 53e6b7f95ae32..ee1be48417222 100644 --- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs +++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs @@ -303,7 +303,7 @@ fn check_expr_for_enum_as_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> Opt ExprKind::Struct(qpath, ..) if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(qpath, expr.hir_id) => { - let ty = cx.tcx.type_of(def_id).instantiate_identity(); + let ty = cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if let ty::FnDef(ctor_def_id, _) = ty.kind() { def_id = *ctor_def_id; } @@ -324,7 +324,7 @@ fn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option PatKind::Struct(qpath, ..) if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) => { - let ty = cx.tcx.type_of(def_id).instantiate_identity(); + let ty = cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if let ty::FnDef(ctor_def_id, _) = ty.kind() { def_id = *ctor_def_id; } diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index 1a56c8f810ee7..2a8b6778fd0ac 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -42,7 +42,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { for var in def.variants { if let Some(anon_const) = &var.disr_expr { let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); - let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity(); + let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity().skip_norm_wip(); let constant = cx.tcx.const_eval_poly(def_id.to_def_id()).ok(); if let Some(Constant::Int(val)) = constant.and_then(|c| mir_to_const(cx.tcx, c, ty)) { if let ty::Adt(adt, _) = ty.kind() diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs index 32be1ad1e644d..4b9e3cee011c6 100644 --- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs +++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError { ItemKind::TyAlias(ident, ..) if ident.name == sym::Error && is_visible_outside_module(cx, item.owner_id.def_id) - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error) && implements_trait(cx, ty, error_def_id, &[]) => { diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs index 12cf829167393..3609b069a2a02 100644 --- a/src/tools/clippy/clippy_lints/src/format_args.rs +++ b/src/tools/clippy/clippy_lints/src/format_args.rs @@ -14,6 +14,7 @@ use clippy_utils::source::{SpanRangeExt, snippet}; use clippy_utils::ty::implements_trait; use clippy_utils::{is_from_proc_macro, is_in_test, sym, trait_ref_of_method}; use itertools::Itertools; +use rustc_middle::ty::Unnormalized; use rustc_ast::{ FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions, FormatPlaceholder, FormatTrait, @@ -689,7 +690,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { } let depth = depth + 1; let typing_env = cx.typing_env(); - let ty = tcx.normalize_erasing_regions(typing_env, ty); + let ty = tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)); match ty.kind() { ty::RawPtr(..) | ty::FnPtr(..) | ty::FnDef(..) => true, ty::Ref(_, t, _) | ty::Slice(t) | ty::Array(t, _) => self.has_pointer_debug(*t, depth), @@ -724,7 +725,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> { }; let pointer_debug = derived_debug && adt.all_fields().any(|f| { - self.has_pointer_debug(tcx.normalize_erasing_regions(typing_env, f.ty(tcx, args)), depth) + self.has_pointer_debug(tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(f.ty(tcx, args))), depth) }); self.has_pointer_format.insert(ty, pointer_debug); pointer_debug diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 79ffe1ea417e4..944c4eee90257 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { // `impl Into for self_ty` && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args && span_is_local(item.span) - && let middle_trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity() + && let middle_trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity().skip_norm_wip() && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::AliasTy { kind: ty::Opaque{..} , .. })) && self.msrv.meets(cx, msrvs::RE_REBALANCING_COHERENCE) diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs index cc9dc47e15f2b..c5c0cc0b5ab61 100644 --- a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs +++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs @@ -107,7 +107,7 @@ pub(crate) fn check_fn<'a>( check_fn_sig(cx, decl, inputs_output_span, sig); } else if !is_trait_impl_item(cx, hir_id) { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); + let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().skip_binder(); if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) { return; @@ -128,7 +128,7 @@ pub(super) fn check_trait_item<'a>( && !is_from_proc_macro(cx, trait_item) { let def_id = trait_item.owner_id.def_id; - let ty_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); + let ty_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().skip_binder(); check_fn_sig(cx, sig.decl, sig.span, ty_sig); } } diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index 77fec93714252..829f054d8854e 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -25,7 +25,7 @@ fn result_err_ty<'tcx>( && let hir::FnRetTy::Return(hir_ty) = decl.output && let ty = cx .tcx - .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output()) + .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip().output()) && ty.is_diag_item(cx, sym::Result) && let ty::Adt(_, args) = ty.kind() { diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index eb54585466900..367fbcb18891d 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -9,6 +9,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{ self, AliasTy, Binder, ClauseKind, PredicateKind, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor, + Unnormalized, }; use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; @@ -80,8 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send) && let preds = cx.tcx.explicit_item_self_bounds(def_id) // If is a Future - && preds - .iter_instantiated_copied(cx.tcx, args) + && preds.iter_instantiated_copied(cx.tcx, args).map(Unnormalized::skip_normalization) .filter_map(|(p, _)| p.as_trait_clause()) .any(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait) { diff --git a/src/tools/clippy/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs b/src/tools/clippy/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs index dec08d94e89dc..56de38f8ed765 100644 --- a/src/tools/clippy/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs +++ b/src/tools/clippy/clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs @@ -79,7 +79,7 @@ impl LateLintPass<'_> for ImplHashWithBorrowStrBytes { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { if let ItemKind::Impl(imp) = item.kind && let Some(of_trait) = imp.of_trait - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let Some(hash_id) = cx.tcx.get_diagnostic_item(sym::Hash) && Res::Def(DefKind::Trait, hash_id) == of_trait.trait_ref.path.res && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow) diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index ee3619ea6746b..25f8d6aa86874 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -358,7 +358,7 @@ fn check_with_condition<'tcx>( if name.ident.name == sym::MIN && let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id) && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(const_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_integral() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_integral() { print_lint_and_sugg(cx, var_name, expr); } @@ -368,7 +368,7 @@ fn check_with_condition<'tcx>( && name.ident.name == sym::min_value && let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id) && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(func_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_integral() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_integral() { print_lint_and_sugg(cx, var_name, expr); } diff --git a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs index 511df733ed910..b7cbe667b3346 100644 --- a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs +++ b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs @@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom { .associated_items(item.owner_id.def_id) .filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type) { - let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity(); + let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity().skip_norm_wip(); if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) { let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id())); let ii_ty_span = cx diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 14928a1be13bc..257a165ba8315 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { } for impl_id in impl_ids.iter().map(|id| id.expect_local()) { - let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity(); + let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip(); let hir_id = cx.tcx.local_def_id_to_hir_id(impl_id); let criterion = match self.scope { InherentImplLintScope::Module => Criterion::Module(cx.tcx.parent_module(hir_id)), diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs index 753360906d666..0abc659b5214d 100644 --- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::implements_trait; +use rustc_middle::ty::Unnormalized; use rustc_hir::def_id::LocalDefId; use rustc_hir::{FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -67,10 +68,9 @@ fn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDe if sig.decl.implicit_self.has_implicit_self() { let ret_ty = cx .tcx - .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().output()); + .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().skip_norm_wip().output()); let ret_ty = cx - .tcx - .try_normalize_erasing_regions(cx.typing_env(), ret_ty) + .tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ret_ty)) .unwrap_or(ret_ty); if cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs index 4e56f9c8472de..5157c989897a9 100644 --- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs +++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs @@ -134,7 +134,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { .trait_def_id() .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did)) && !item.span.in_external_macro(cx.sess().source_map()) - && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() + && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip().kind() && let expected_method_name = match mtbl { Mutability::Mut => sym::iter_mut, Mutability::Not => sym::iter, @@ -211,7 +211,7 @@ impl {self_ty_without_ref} {{ && imp.of_trait.is_none() && let sig = cx.tcx.liberate_late_bound_regions( item_did, - cx.tcx.fn_sig(item_did).instantiate_identity() + cx.tcx.fn_sig(item_did).instantiate_identity().skip_norm_wip() ) && let ref_ty = sig.inputs()[0] && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator) diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 383f2721fad21..f3821a430bad3 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -1,5 +1,6 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; +use rustc_middle::ty::Unnormalized; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -54,10 +55,9 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { // doesn't account for empty where-clauses that only consist of keyword `where` IINM. && generics.params.is_empty() && !generics.has_where_clause_predicates && !item.span.from_expansion() - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let ty::Array(element_type, cst) = ty.kind() - && let Some(element_count) = cx.tcx - .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_target_usize(cx.tcx) + && let Some(element_count) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(*cst)).unwrap_or(*cst).try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size) { diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index 50767b32bb71d..f5af7acdcf51d 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -75,7 +75,7 @@ impl LargeEnumVariant { impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) { if let ItemKind::Enum(ident, _, ref def) = item.kind - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let ty::Adt(adt, subst) = ty.kind() && adt.variants().len() > 1 && !item.span.in_external_macro(cx.tcx.sess.source_map()) diff --git a/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs b/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs index 60dbd6cd3570f..f859b35aa9d3a 100644 --- a/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/len_without_is_empty.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty { && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id() && let Some(local_id) = ty_id.as_local() && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id) - && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()) + && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_norm_wip().skip_binder()) { let (name, kind) = match cx.tcx.hir_node(ty_hir_id) { Node::ForeignItem(x) => (x.ident.name, "extern type"), @@ -313,7 +313,7 @@ fn check_for_is_empty( if !(is_empty.is_method() && check_is_empty_sig( cx, - cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), + cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_norm_wip().skip_binder(), len_self_kind, len_output, )) => diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index 40d1d36bd162c..6ee93fa759a98 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -139,7 +139,7 @@ fn is_ref_iterable<'tcx>( } let res_ty = cx.tcx.erase_and_anonymize_regions( - EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)), + EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)).skip_norm_wip(), ); let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { Some(mutbl) diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index f1b7d4bdfa932..307b8fcec1506 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -397,7 +397,7 @@ impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> { ExprKind::MethodCall(_, receiver, args, _) => { let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); for (ty, expr) in iter::zip( - self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(), + self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder(), iter::once(receiver).chain(args.iter()), ) { self.prefer_mutable = false; diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs index 6a02bb38d17b5..5089bd9e14e4a 100644 --- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs +++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs @@ -102,7 +102,7 @@ fn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(expr); if let ty::FnDef(id, _) = *ty.kind() - && let Some(fn_type) = cx.tcx.fn_sig(id).instantiate_identity().no_bound_vars() + && let Some(fn_type) = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip().no_bound_vars() { return is_unit_type(fn_type.output()); } diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs index 9c6cf66019f01..02382ce741fc2 100644 --- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs @@ -129,8 +129,7 @@ fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_> if let ItemKind::Fn { .. } = item.kind { let output = cx .tcx - .fn_sig(item.owner_id) - .instantiate_identity() + .fn_sig(item.owner_id).instantiate_identity().skip_norm_wip() .output() .skip_binder(); return same_type_modulo_regions(output, cx.typeck_results().expr_ty(expr)); diff --git a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs index 1130d82ab78f9..4a0da63681064 100644 --- a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs +++ b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs @@ -9,7 +9,7 @@ pub(crate) fn check(cx: &LateContext<'_>, pat: &Pat<'_>) { if !pat.span.from_expansion() && let PatKind::Struct(QPath::Resolved(_, path), fields, Some(dotdot)) = pat.kind && let Some(def_id) = path.res.opt_def_id() - && let ty = cx.tcx.type_of(def_id).instantiate_identity() + && let ty = cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip() && let ty::Adt(def, _) = ty.kind() && (def.is_struct() || def.is_union()) && fields.len() == def.non_enum_variant().fields.len() diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 4267cd1185523..213c09bc3cfec 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -344,7 +344,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> { }; let fn_sig = if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(parent_expr.hir_id) { - self.cx.tcx.fn_sig(def_id).instantiate_identity() + self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip() } else { return; }; diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs index baea49296cd7a..5abdd82f1cde2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>( ) { if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(bytes_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_str() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_str() && let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs() && (ty.is_str() || ty.is_lang_item(cx, hir::LangItem::String)) { diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index 229670486db3f..15f4d91e4bd9e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_str() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_str() && let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), .. diff --git a/src/tools/clippy/clippy_lints/src/methods/get_first.rs b/src/tools/clippy/clippy_lints/src/methods/get_first.rs index cb5d1ec374fce..c3598eb59478a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/get_first.rs +++ b/src/tools/clippy/clippy_lints/src/methods/get_first.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( ) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) - && let identity = cx.tcx.type_of(impl_id).instantiate_identity() + && let identity = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip() && let hir::ExprKind::Lit(Spanned { node: LitKind::Int(Pu128(0), _), .. diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs index 57c0ba25ebbf0..768612d6bbdc1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs @@ -49,7 +49,7 @@ pub fn is_clone_like(cx: &LateContext<'_>, method_name: Symbol, method_parent_id sym::to_string => method_parent_id.is_diag_item(cx, sym::ToString), sym::to_vec => method_parent_id .opt_impl_ty(cx) - .is_some_and(|ty| ty.instantiate_identity().is_slice()), + .is_some_and(|ty| ty.instantiate_identity().skip_norm_wip().is_slice()), _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs index cdef98be14af3..a69671faae783 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs @@ -86,7 +86,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method ExprKind::MethodCall(_name, recv, args, _span) => cx .typeck_results() .type_dependent_def_id(parent.hir_id) - .and_then(|def_id| ty_sig(cx, cx.tcx.type_of(def_id).instantiate_identity())) + .and_then(|def_id| ty_sig(cx, cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip())) .is_some_and(|fn_sig| { is_arg_ty_unified_in_fn(cx, fn_sig, child_id, once(recv).chain(args.iter()), true) }), diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs index a8e30e44488cc..8f18de41e8a37 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs @@ -20,8 +20,7 @@ pub(super) fn check<'tcx>( && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx .tcx - .type_of(impl_id) - .instantiate_identity() + .type_of(impl_id).instantiate_identity().skip_norm_wip() .is_diag_item(cx, sym::Option) && let ExprKind::Call(err_path, [err_arg]) = or_expr.kind && err_path.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr) diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs index f7da24bed2b80..3e59e0a642cd2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs @@ -11,8 +11,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx .tcx - .type_of(impl_id) - .instantiate_identity() + .type_of(impl_id).instantiate_identity().skip_norm_wip() .is_diag_item(cx, sym::Result) && let ExprKind::Closure(&Closure { capture_clause: CaptureBy::Ref, diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index b39aec6e521ce..50cfabbabf589 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -5054,10 +5054,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind { let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir_expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); + let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); - let method_sig = cx.tcx.fn_sig(impl_item.owner_id).instantiate_identity(); + let method_sig = cx.tcx.fn_sig(impl_item.owner_id).instantiate_identity().skip_norm_wip(); let method_sig = cx.tcx.instantiate_bound_regions_with_erased(method_sig); let first_arg_ty_opt = method_sig.inputs().iter().next().copied(); should_implement_trait::check_impl_item(cx, impl_item, self_ty, implements_trait, first_arg_ty_opt, sig); @@ -5093,8 +5093,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { && let Some(first_arg_hir_ty) = sig.decl.inputs.first() && let Some(&first_arg_ty) = cx .tcx - .fn_sig(item.owner_id) - .instantiate_identity() + .fn_sig(item.owner_id).instantiate_identity().skip_norm_wip() .inputs() .skip_binder() .first() diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index debe433393cd4..9dcb731c14215 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -8,6 +8,7 @@ use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{has_non_owning_mutable_access, make_normalized_projection, make_projection}; use clippy_utils::{CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, sym}; +use rustc_middle::ty::Unnormalized; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt}; @@ -194,7 +195,7 @@ fn check_collect_into_intoiterator<'tcx>( // that contains `collect_expr` let inputs = cx .tcx - .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity()) + .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip()) .inputs(); // map IntoIterator generic bounds to their signature @@ -233,7 +234,7 @@ fn check_collect_into_intoiterator<'tcx>( /// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool` fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { cx.typeck_results().type_dependent_def_id(call_id).is_some_and(|id| { - let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder(); + let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip().skip_binder(); sig.inputs().len() == 1 && sig.output().is_bool() }) } @@ -245,10 +246,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty]) && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) - && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( - cx.typing_env(), - Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.kind.def_id(), into_iter_item_proj.args), - ) + && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.kind.def_id(), into_iter_item_proj.args))) { iter_item_ty == into_iter_item_ty } else { @@ -261,7 +259,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool { let typeck = cx.typeck_results(); if let Some(id) = typeck.type_dependent_def_id(call_id) - && let sig = cx.tcx.fn_sig(id).instantiate_identity() + && let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip() && sig.skip_binder().output().is_bool() && let [_, search_ty] = *sig.skip_binder().inputs() && let ty::Ref(_, search_ty, Mutability::Not) = *cx @@ -277,9 +275,9 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - ) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = Ty::new_projection_from_args(cx.tcx, iter_item.def_id, args) - && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), proj_ty) + && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(proj_ty)) { - item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)) + item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)).skip_norm_wip() } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index 36dd4e952a2d9..3ce28e41e6b78 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -18,7 +18,7 @@ fn is_open_options(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) - && is_open_options(cx, cx.tcx.type_of(impl_id).instantiate_identity()) + && is_open_options(cx, cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip()) { let mut options = Vec::new(); if get_open_options(cx, recv, &mut options) { diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index e12cce93c2a47..a5d88a49ab341 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -135,7 +135,7 @@ fn check_unwrap_or_default( let output_type_implements_default = |fun| { let fun_ty = cx.typeck_results().expr_ty(fun); if let ty::FnDef(def_id, args) = *fun_ty.kind() { - let output_ty = cx.tcx.fn_sig(def_id).instantiate(cx.tcx, args).skip_binder().output(); + let output_ty = cx.tcx.fn_sig(def_id).instantiate(cx.tcx, args).skip_norm_wip().skip_binder().output(); cx.tcx .get_diagnostic_item(sym::Default) .is_some_and(|default_trait_id| implements_trait(cx, output_ty, default_trait_id, &[])) diff --git a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs index fe4904804b5b7..401e678b96ba7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -14,8 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx .tcx - .type_of(impl_id) - .instantiate_identity() + .type_of(impl_id).instantiate_identity().skip_norm_wip() .is_diag_item(cx, sym::PathBuf) && let ExprKind::Lit(lit) = arg.kind && let LitKind::Str(ref path_lit, _) = lit.node diff --git a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs index 17d1a6abde0a8..23a5ae2a866b5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs +++ b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs @@ -10,7 +10,7 @@ use super::STABLE_SORT_PRIMITIVE; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_slice() && let Some(slice_type) = is_slice_of_primitives(cx, recv) { span_lint_and_then( diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs index cbb7da327506d..3a4c71fed3b5d 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs @@ -10,7 +10,7 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, if count <= 1 && let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(call_id) - && let self_ty = cx.tcx.type_of(impl_id).instantiate_identity() + && let self_ty = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip() && (self_ty.is_slice() || self_ty.is_str()) { // Ignore empty slice and string literals when used with a literal count. diff --git a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs index 418eb4a6b2ac4..286fc0a64a2dd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs +++ b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs @@ -7,7 +7,7 @@ use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind}; use rustc_middle::ty::print::with_forced_trimmed_paths; -use rustc_middle::ty::{self, ExistentialPredicate, Ty}; +use rustc_middle::ty::{self, ExistentialPredicate, Ty, Unnormalized}; use rustc_span::Span; /// Checks if the given type is `dyn Any`, or a trait object that has `Any` as a supertrait. @@ -25,8 +25,7 @@ fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { cx.tcx.is_diagnostic_item(sym::Any, tr.def_id) || cx .tcx - .explicit_super_predicates_of(tr.def_id) - .iter_identity_copied() + .explicit_super_predicates_of(tr.def_id).iter_identity_copied().map(Unnormalized::skip_normalization) .any(|(clause, _)| { matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(super_tr) if cx.tcx.is_diagnostic_item(sym::Any, super_tr.def_id())) diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index 3f81a6ecd2f8c..281d9e5f712f7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -243,7 +243,7 @@ fn mapping_of_mirrored_pats(a_pat: &Pat<'_>, b_pat: &Pat<'_>) -> Option, expr: &Expr<'_>, arg: &Expr<'_>) -> Option { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) - && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() + && cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip().is_slice() && let ExprKind::Closure(&Closure { body, .. }) = arg.kind && let closure_body = cx.tcx.hir_body(body) && let &[Param { pat: l_pat, .. }, Param { pat: r_pat, .. }] = closure_body.params diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index af5498c353d43..d696bdfa6bd43 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -382,7 +382,7 @@ fn check_other_call_arg<'tcx>( ) -> bool { if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr) && let Some((callee_def_id, _, recv, call_args)) = get_callee_generic_args_and_args(cx, maybe_call) - && let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder() + && let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_norm_wip().skip_binder() && let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id) && let Some(input) = fn_sig.inputs().get(i) && let (input, n_refs, _) = peel_and_count_ty_refs(*input) @@ -569,7 +569,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< })); if trait_predicates.any(|predicate| { - let predicate = bound_fn_sig.rebind(predicate).instantiate(cx.tcx, new_subst); + let predicate = bound_fn_sig.rebind(predicate).instantiate(cx.tcx, new_subst).skip_norm_wip(); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); !cx.tcx .infer_ctxt() @@ -698,7 +698,7 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx sym::to_vec => cx .tcx .impl_of_assoc(method_def_id) - .is_some_and(|impl_did| cx.tcx.type_of(impl_did).instantiate_identity().is_slice()), + .is_some_and(|impl_did| cx.tcx.type_of(impl_did).instantiate_identity().skip_norm_wip().is_slice()), _ => false, } && let original_arg_ty = cx.typeck_results().node_type(caller.hir_id).peel_refs() diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs index c07c932176462..ad7b0fc47cf3a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs @@ -74,7 +74,7 @@ pub(super) fn check( } for &def_id in unwrap_allowed_aliases { - let alias_ty = cx.tcx.type_of(def_id).instantiate_identity(); + let alias_ty = cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); if let (ty::Adt(adt, substs), ty::Adt(alias_adt, alias_substs)) = (ty.kind(), alias_ty.kind()) && adt.did() == alias_adt.did() { diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index 1e1b124b44866..012a148bb2a29 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -111,7 +111,7 @@ impl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> { ExprKind::MethodCall(.., args, _) => { if args.iter().all(|arg| !self.is_binding(arg)) && let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id) - && let method_ty = self.cx.tcx.type_of(method_def_id).instantiate_identity() + && let method_ty = self.cx.tcx.type_of(method_def_id).instantiate_identity().skip_norm_wip() && let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder() && matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not)) { diff --git a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs index 8979f9973d6f6..029b94bfef0e3 100644 --- a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs @@ -20,8 +20,7 @@ pub(super) fn check<'tcx>( && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id) && cx .tcx - .type_of(impl_id) - .instantiate_identity() + .type_of(impl_id).instantiate_identity().skip_norm_wip() .is_diag_item(cx, sym::Vec) && let ExprKind::Lit(Spanned { node: LitKind::Int(Pu128(0), _), diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index 99c3266718436..0839219c5b613 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -203,7 +203,7 @@ fn could_be_const_with_abi(cx: &LateContext<'_>, msrv: Msrv, abi: ExternAbi) -> /// Return `true` when the given `def_id` is a function that has `impl Trait` ty as one of /// its parameter types. fn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { - let inputs = cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(); + let inputs = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder(); inputs.iter().any(|input| { matches!( input.kind(), diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 86438a1753bdc..93282545bf2a1 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -110,7 +110,7 @@ impl<'tcx> MutableKeyType<'tcx> { } fn check_sig(&mut self, cx: &LateContext<'tcx>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'tcx>) { - let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity().skip_norm_wip(); for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) { self.check_ty_(cx, hir_ty.span, *ty); } diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 1374d8ed774ba..dc4f91a0f5754 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -5,6 +5,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_copy}; use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_n_hir_expr_refs, sym}; +use rustc_middle::ty::Unnormalized; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -178,7 +179,7 @@ fn needless_borrow_count<'tcx>( let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait(); let drop_trait_def_id = cx.tcx.lang_items().drop_trait(); - let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder(); + let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_norm_wip().skip_binder(); let predicates = cx.tcx.param_env(fn_id).caller_bounds(); let projection_predicates = predicates .iter() @@ -279,7 +280,7 @@ fn needless_borrow_count<'tcx>( return false; } - let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]); + let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]).skip_norm_wip(); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); infcx.predicate_must_hold_modulo_regions(&obligation) @@ -305,8 +306,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool { if assoc_item.is_method() { let self_ty = cx .tcx - .fn_sig(assoc_item.def_id) - .instantiate_identity() + .fn_sig(assoc_item.def_id).instantiate_identity().skip_norm_wip() .skip_binder() .inputs()[0]; matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut)) @@ -427,7 +427,7 @@ fn replace_types<'tcx>( .expect_ty(cx.tcx) .to_ty(cx.tcx); - if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), projection) + if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(projection)) && args[term_param_ty.index as usize] != GenericArg::from(projected_ty) { deque.push_back((*term_param_ty, projected_ty)); diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index d718751e34281..2ff9b7beff1c8 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -4,7 +4,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{ClauseKind, PredicatePolarity}; +use rustc_middle::ty::{ClauseKind, PredicatePolarity, Unnormalized}; use rustc_session::declare_lint_pass; use rustc_span::symbol::Ident; @@ -92,7 +92,7 @@ fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) -> return true; } - for (predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).iter_identity_copied() { + for (predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).iter_identity_copied().map(Unnormalized::skip_normalization) { if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && trait_predicate.polarity == PredicatePolarity::Positive && !path.contains(&trait_predicate.def_id()) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 2b1f7574a83ac..74a37077b0a1d 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -173,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { return; } - let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity().skip_norm_wip(); let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig); // If there are no `&mut` argument, no need to go any further. diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index fb5f21acf2af2..593eff6a9bbd1 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ctx }; - let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity().skip_norm_wip(); let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig); for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(body.params).enumerate() { diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index ce8ce2aa900a0..430b6f055f5f3 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -90,14 +90,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { && impl_item.generics.params.is_empty() && sig.decl.inputs.is_empty() && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) - && let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && self_ty == return_ty(cx, impl_item.owner_id) && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) { if self.impling_types.is_none() { let mut impls = HirIdSet::default(); for &d in cx.tcx.local_trait_impls(default_trait_id) { - let ty = cx.tcx.type_of(d).instantiate_identity(); + let ty = cx.tcx.type_of(d).instantiate_identity().skip_norm_wip(); if let Some(ty_def) = ty.ty_adt_def() && let Some(local_def_id) = ty_def.did().as_local() { @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // Check if a Default implementation exists for the Self type, regardless of // generics if let Some(ref impling_types) = self.impling_types - && let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && let Some(self_def) = self_def.ty_adt_def() && let Some(self_local_did) = self_def.did().as_local() && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did) diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 7163daa5b0f3a..d56e9cb92e57f 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -154,8 +154,7 @@ impl NoEffect { let expr_ty = cx.typeck_results().expr_ty(expr); let mut ret_ty = cx .tcx - .fn_sig(item.owner_id) - .instantiate_identity() + .fn_sig(item.owner_id).instantiate_identity().skip_norm_wip() .output() .skip_binder(); diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index ea460803ef027..61e57d93f85cd 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -24,6 +24,7 @@ use clippy_utils::macros::macro_backtrace; use clippy_utils::paths::{PathNS, lookup_path_str}; use clippy_utils::ty::{get_field_idx_by_name, implements_trait}; use clippy_utils::{is_in_const_context, sym}; +use rustc_middle::ty::Unnormalized; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdSet}; @@ -277,7 +278,7 @@ impl<'tcx> NonCopyConst<'tcx> { /// Checks if a value of the given type is `Freeze`, or may be depending on the value. fn is_ty_freeze(&mut self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>) -> IsFreeze { // FIXME: this should probably be using the trait solver - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); match self.freeze_tys.entry(ty) { Entry::Occupied(e) => *e.get(), Entry::Vacant(e) => { @@ -345,7 +346,7 @@ impl<'tcx> NonCopyConst<'tcx> { ty: Ty<'tcx>, val: ConstValue, ) -> Result { - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); match self.is_ty_freeze(tcx, typing_env, ty) { IsFreeze::Yes => Ok(true), IsFreeze::Maybe if matches!(ty.kind(), ty::Adt(..) | ty::Array(..) | ty::Tuple(..)) => { @@ -380,8 +381,8 @@ impl<'tcx> NonCopyConst<'tcx> { e: &'tcx Expr<'tcx>, ) -> bool { // Make sure to instantiate all types coming from `typeck` with `gen_args`. - let ty = EarlyBinder::bind(typeck.expr_ty(e)).instantiate(tcx, gen_args); - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = EarlyBinder::bind(typeck.expr_ty(e)).instantiate(tcx, gen_args).skip_norm_wip(); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); match self.is_ty_freeze(tcx, typing_env, ty) { IsFreeze::Yes => true, IsFreeze::No => false, @@ -395,7 +396,7 @@ impl<'tcx> NonCopyConst<'tcx> { }, ExprKind::Path(ref p) => { let res = typeck.qpath_res(p, e.hir_id); - let gen_args = EarlyBinder::bind(typeck.node_args(e.hir_id)).instantiate(tcx, gen_args); + let gen_args = EarlyBinder::bind(typeck.node_args(e.hir_id)).instantiate(tcx, gen_args).skip_norm_wip(); match res { Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did) if let Ok(val) = @@ -447,7 +448,7 @@ impl<'tcx> NonCopyConst<'tcx> { loop { let ty = typeck.expr_ty(src_expr); // Normalized as we need to check if this is an array later. - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); let is_freeze = self.is_ty_freeze(tcx, typing_env, ty); if is_freeze.is_freeze() { return None; @@ -488,7 +489,7 @@ impl<'tcx> NonCopyConst<'tcx> { let mut ty = typeck.expr_ty(src_expr); loop { // Normalized as we need to check if this is an array later. - ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); if let [adjust, ..] = typeck.expr_adjustments(src_expr) { let res = if let Some(cause) = does_adjust_borrow(adjust) && !self.is_value_freeze(tcx, typing_env, ty, val)? @@ -588,7 +589,7 @@ impl<'tcx> NonCopyConst<'tcx> { }, ExprKind::Path(ref init_path) => { let next_init_args = - EarlyBinder::bind(init_typeck.node_args(init_expr.hir_id)).instantiate(tcx, init_args); + EarlyBinder::bind(init_typeck.node_args(init_expr.hir_id)).instantiate(tcx, init_args).skip_norm_wip(); match init_typeck.qpath_res(init_path, init_expr.hir_id) { Res::Def(DefKind::Ctor(..), _) => return None, Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did) @@ -624,7 +625,7 @@ impl<'tcx> NonCopyConst<'tcx> { // gets cached. let ty = typeck.expr_ty(src_expr); // Normalized as we need to check if this is an array later. - let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); + let ty = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty); if self.is_ty_freeze(tcx, typing_env, ty).is_freeze() { return None; } @@ -702,7 +703,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if let ItemKind::Const(ident, .., ct_rhs) = item.kind && !ident.is_special() - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, IsFreeze::Yes => false, @@ -743,7 +744,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if let TraitItemKind::Const(_, ct_rhs_opt, _) = item.kind - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, IsFreeze::Maybe if let Some(ct_rhs) = ct_rhs_opt => { @@ -778,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, ct_rhs) = item.kind - && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() + && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::Yes => false, IsFreeze::No => { @@ -795,9 +796,9 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { let ty = (ReplaceAssocFolder { tcx: cx.tcx, trait_id, - self_ty: cx.tcx.type_of(parent_item.owner_id).instantiate_identity(), + self_ty: cx.tcx.type_of(parent_item.owner_id).instantiate_identity().skip_norm_wip(), }) - .fold_ty(cx.tcx.type_of(item.owner_id).instantiate_identity()); + .fold_ty(cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip()); // `ty` may not be normalizable, but that should be fine. !self.is_ty_freeze(cx.tcx, cx.typing_env(), ty).is_not_freeze() } else { diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index c6ed0082016ff..6f1fca8d402ee 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { && send_trait == trait_id && of_trait.polarity == ImplPolarity::Positive && let ty_trait_ref = cx.tcx.impl_trait_ref(item.owner_id) - && let self_ty = ty_trait_ref.instantiate_identity().self_ty() + && let self_ty = ty_trait_ref.instantiate_identity().skip_norm_wip().self_ty() && let ty::Adt(adt_def, impl_trait_args) = self_ty.kind() { let mut non_send_fields = Vec::new(); diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 6c45964da0dab..0cbeec4b34fba 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -333,7 +333,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { && let Ok(trait_item_id) = trait_item_def_id { let impl_id = cx.tcx.local_parent(owner_id.def_id); - let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity(); + let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity().skip_norm_wip(); ( trait_item_id, FnKind::ImplTraitFn( diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs index ce50e6e35dcc5..b13766215df82 100644 --- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs +++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs @@ -283,7 +283,7 @@ fn is_assoc_fn_without_type_instance<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<' .. }, )) = func.kind - && let output_ty = cx.tcx.fn_sig(*def_id).instantiate_identity().skip_binder().output() + && let output_ty = cx.tcx.fn_sig(*def_id).instantiate_identity().skip_norm_wip().skip_binder().output() && let ty::Param(ty::ParamTy { name: kw::SelfUpper, .. }) = output_ty.kind() diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 6cb57b1d3b368..b4a1713222123 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -130,7 +130,7 @@ impl PassByRefOrValue { return; } - let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir_body(id)); // Gather all the lifetimes found in the output type which may affect whether diff --git a/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs b/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs index 4bfff64b1bd48..ea1be8899b292 100644 --- a/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs +++ b/src/tools/clippy/clippy_lints/src/ptr/ptr_arg.rs @@ -36,7 +36,7 @@ pub(super) fn check_body<'tcx>( } let decl = sig.decl; - let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder(); + let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_norm_wip().skip_binder(); let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params) .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not) .collect(); @@ -68,7 +68,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item_id: OwnerId, s for arg in check_fn_args( cx, - cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder(), + cx.tcx.fn_sig(item_id).instantiate_identity().skip_norm_wip().skip_binder(), sig.decl.inputs, &[], ) diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs index 39019c646bd5a..7c0ebe8fecb2e 100644 --- a/src/tools/clippy/clippy_lints/src/ranges.rs +++ b/src/tools/clippy/clippy_lints/src/ranges.rs @@ -401,7 +401,7 @@ fn can_switch_ranges<'tcx>( }; let inputs = cx .tcx - .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity()) + .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip()) .inputs(); let expr_ty = inputs[input_idx]; // Check that the `expr` type is present only once, otherwise modifying just one of them might be @@ -445,8 +445,7 @@ fn can_switch_ranges<'tcx>( } && let switched_range_ty = cx .tcx - .type_of(switched_range_def_id) - .instantiate(cx.tcx, &[inner_ty.into()]) + .type_of(switched_range_def_id).instantiate(cx.tcx, &[inner_ty.into()]).skip_norm_wip() // Check that the switched range type can be used for indexing the original expression // through the `Index` or `IndexMut` trait. && let ty::Ref(_, outer_ty, mutability) = cx.typeck_results().expr_ty_adjusted(outer_expr).kind() diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 1637156d7c377..09730a19a23dc 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -3,6 +3,7 @@ use clippy_utils::get_parent_expr; use clippy_utils::res::MaybeDef; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::peel_and_count_ty_refs; +use rustc_middle::ty::Unnormalized; use rustc_ast::util::parser::ExprPrecedence; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; @@ -140,10 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { diag.span_suggestion(expr.span, help_msg, sugg, app); }); } else if let Some(target_id) = cx.tcx.lang_items().deref_target() - && let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( - cx.typing_env(), - Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])), - ) + && let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])))) && deref_ty == expr_ty { let (lint, msg) = DEREF_BY_SLICING_LINT; diff --git a/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs b/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs index b19935959c4d8..31ae6811e3aa9 100644 --- a/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs +++ b/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs @@ -71,8 +71,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) if let Some(def_id) = fn_def_id(cx, e) && cx .tcx - .fn_sig(def_id) - .instantiate_identity() + .fn_sig(def_id).instantiate_identity().skip_norm_wip() .skip_binder() .output() .walk() diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 534ba3a50c6b4..07117e247c655 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir_expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); + let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(); let ret_ty = return_ty(cx, impl_item.owner_id); // Do not check trait impls diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index 3e77c98b88456..12ce318969686 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::res::MaybeResPath; use clippy_utils::source::{indent_of, snippet}; use clippy_utils::{expr_or_init, get_builtin_attr, peel_hir_expr_unary, sym}; +use rustc_middle::ty::Unnormalized; use rustc_ast::BindingMode; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::Applicability; @@ -153,8 +154,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { } let ty = self .cx - .tcx - .try_normalize_erasing_regions(self.cx.typing_env(), ty) + .tcx.try_normalize_erasing_regions(self.cx.typing_env(), Unnormalized::new_wip(ty)) .unwrap_or(ty); match self.type_cache.entry(ty) { Entry::Occupied(e) => return *e.get(), diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 8bac517682db3..3a9e2e05648b9 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -60,10 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool { if let ItemKind::Struct(_, _, data) = &item.kind && let Some(last_field) = data.fields().last() - && let field_ty = cx.tcx.normalize_erasing_regions( - cx.typing_env(), - cx.tcx.type_of(last_field.def_id).instantiate_identity(), - ) + && let field_ty = cx.tcx.normalize_erasing_regions(cx.typing_env(), cx.tcx.type_of(last_field.def_id).instantiate_identity()) && let ty::Array(_, array_len) = *field_ty.kind() && let Some(0) = array_len.try_to_target_usize(cx.tcx) { diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index c097f7773099a..d5a9006095da1 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -1,6 +1,7 @@ use super::TRANSMUTE_UNDEFINED_REPR; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::is_c_void; +use rustc_middle::ty::Unnormalized; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::{self, GenericArgsRef, IntTy, Ty, UintTy}; @@ -240,7 +241,7 @@ enum ReducedTy<'tcx> { /// Reduce structs containing a single non-zero sized field to it's contained type. fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> { loop { - ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty); + ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)).unwrap_or(ty); return match *ty.kind() { ty::Pat(base, _) => { ty = base; @@ -270,7 +271,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> .non_enum_variant() .fields .iter() - .map(|f| cx.tcx.type_of(f.did).instantiate(cx.tcx, args)); + .map(|f| cx.tcx.type_of(f.did).instantiate(cx.tcx, args).skip_norm_wip()); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure { raw_ptr_only: false }; }; @@ -297,7 +298,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> } fn is_zero_sized_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) + if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)) && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty)) { layout.layout.size().bytes() == 0 diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs index 5baa67b1f3e8a..74494aff0cb62 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs @@ -1,3 +1,4 @@ +use rustc_middle::ty::Unnormalized; use rustc_lint::LateContext; use rustc_middle::ty::Ty; @@ -5,8 +6,8 @@ use rustc_middle::ty::Ty; // size or alignment pub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { let typing_env = cx.typing_env(); - if let Ok(from) = cx.tcx.try_normalize_erasing_regions(typing_env, from) - && let Ok(to) = cx.tcx.try_normalize_erasing_regions(typing_env, to) + if let Ok(from) = cx.tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(from)) + && let Ok(to) = cx.tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(to)) && let Ok(from_layout) = cx.tcx.layout_of(typing_env.as_query_input(from)) && let Ok(to_layout) = cx.tcx.layout_of(typing_env.as_query_input(to)) { diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 39f4130afcf36..735225a9e2cee 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -89,7 +89,7 @@ fn get_args_to_check<'tcx>( ) -> Vec<(usize, Symbol)> { let mut args_to_check = Vec::new(); if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { - let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); let generics = cx.tcx.predicates_of(def_id); let [fn_mut_preds, ord_preds, partial_ord_preds] = get_trait_predicates_for_trait_ids(cx, generics, &[Some(fn_mut_trait), ord_trait, partial_ord_trait]); diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs index 2a23e5329e9e1..8bb6ceb863a37 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs @@ -317,7 +317,7 @@ fn needs_inferred_result_ty( }, _ => return false, }; - let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder(); + let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip().skip_binder(); if let ty::Param(output_ty) = *sig.output().kind() { let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver { std::iter::once(receiver).chain(args.iter()).collect() diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs b/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs index eb2d7639e91f7..75b0b7b10687a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs @@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) => { let args = cx.typeck_results().node_args(e.hir_id); - let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); + let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args).skip_norm_wip(); check_arguments( cx, &mut iter::once(receiver).chain(arguments.iter()), diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 620874e2aebf8..93d0870a30a21 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { let impl_trait_ref = cx.tcx.impl_trait_ref(impl_id); // `self_ty` is the semantic self type of `impl for `. This cannot be // `Self`. - let self_ty = impl_trait_ref.instantiate_identity().self_ty(); + let self_ty = impl_trait_ref.instantiate_identity().skip_norm_wip().self_ty(); // `trait_method_sig` is the signature of the function, how it is declared in the // trait, not in the impl of the trait. @@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { .tcx .trait_item_of(impl_item.owner_id) .expect("impl method matches a trait method"); - let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity(); + let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity().skip_norm_wip(); let trait_method_sig = cx.tcx.instantiate_bound_regions_with_erased(trait_method_sig); // `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the @@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { && !ty_is_in_generic_args(cx, hir_ty) && !types_to_skip.contains(&hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty()) - && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity() + && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip() && same_type_modulo_regions(ty, impl_ty) // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that // the lifetime parameters of `ty` are elided (`impl<'a> Foo<'a> { fn new() -> Self { Foo{..} } }`), in @@ -232,7 +232,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if !expr.span.from_expansion() && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last() - && cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity() + && cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip() && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS) { match expr.kind { @@ -255,7 +255,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { && let PatKind::Expr(&PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind - && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity() + && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip() && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS) { check_path(cx, path); diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 662da5929adb7..0174b90064b53 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -112,7 +112,7 @@ fn into_iter_bound<'tcx>( } })); - let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args); + let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args).skip_norm_wip(); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); if !cx .tcx diff --git a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs index 6d5c7b86a0aed..a968629ac2dc1 100644 --- a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs @@ -26,14 +26,13 @@ impl LateLintPass<'_> for MsrvAttrImpl { items, .. }) = &item.kind - && let trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity() + && let trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity().skip_norm_wip() && internal_paths::EARLY_LINT_PASS.matches(cx, trait_ref.def_id) && let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind() && self_ty_def.is_struct() && self_ty_def.all_fields().any(|f| { cx.tcx - .type_of(f.did) - .instantiate_identity() + .type_of(f.did).instantiate_identity().skip_norm_wip() .walk() .filter(|t| matches!(t.kind(), GenericArgKind::Type(_))) .any(|t| internal_paths::MSRV_STACK.matches_ty(cx, t.expect_ty())) diff --git a/src/tools/clippy/clippy_lints_internal/src/symbols.rs b/src/tools/clippy/clippy_lints_internal/src/symbols.rs index 779485e49b394..ae74186ea90c2 100644 --- a/src/tools/clippy/clippy_lints_internal/src/symbols.rs +++ b/src/tools/clippy/clippy_lints_internal/src/symbols.rs @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for Symbols { for item in cx.tcx.module_children(*def_id) { if let Res::Def(DefKind::Const { .. }, item_def_id) = item.res - && let ty = cx.tcx.type_of(item_def_id).instantiate_identity() + && let ty = cx.tcx.type_of(item_def_id).instantiate_identity().skip_norm_wip() && internal_paths::SYMBOL.matches_ty(cx, ty) && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id) && let Some(value) = value.to_u32().discard_err() diff --git a/src/tools/clippy/clippy_lints_internal/src/unusual_names.rs b/src/tools/clippy/clippy_lints_internal/src/unusual_names.rs index e11a2868fb69c..b10f4be7497b9 100644 --- a/src/tools/clippy/clippy_lints_internal/src/unusual_names.rs +++ b/src/tools/clippy/clippy_lints_internal/src/unusual_names.rs @@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusualNames { for (param, ty) in body .params .iter() - .zip(cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder().inputs()) + .zip(cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().skip_binder().inputs()) { check_pat_name_for_ty(cx, param.pat, *ty, "parameter"); } diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index d184744162e4e..0e28cdf3b9ca3 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -52,7 +52,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: use EagernessSuggestion::{Eager, Lazy, NoChange}; let ty = match cx.tcx.impl_of_assoc(fn_id) { - Some(id) => cx.tcx.type_of(id).instantiate_identity(), + Some(id) => cx.tcx.type_of(id).instantiate_identity().skip_norm_wip(), None => return Lazy, }; @@ -71,7 +71,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: // Due to the limited operations on these types functions should be fairly cheap. if def.variants().iter().flat_map(|v| v.fields.iter()).any(|x| { matches!( - cx.tcx.type_of(x.did).instantiate_identity().peel_refs().kind(), + cx.tcx.type_of(x.did).instantiate_identity().skip_norm_wip().peel_refs().kind(), ty::Param(_) ) }) && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { @@ -82,8 +82,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: // Limit the function to either `(self) -> bool` or `(&self) -> bool` match &**cx .tcx - .fn_sig(fn_id) - .instantiate_identity() + .fn_sig(fn_id).instantiate_identity().skip_norm_wip() .skip_binder() .inputs_and_output { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 396b63870dea3..38b7c982fe09d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -548,7 +548,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< if let QPath::TypeRelative(_, method) = path && method.ident.name == sym::new && let Some(impl_did) = cx.tcx.impl_of_assoc(def_id) - && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() + && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().skip_norm_wip().ty_adt_def() { return Some(adt.did()) == cx.tcx.lang_items().string() || (cx.tcx.get_diagnostic_name(adt.did())).is_some_and(|adt_name| std_types_symbols.contains(&adt_name)); @@ -1496,13 +1496,13 @@ pub fn is_direct_expn_of(span: Span, name: Symbol) -> Option { /// Convenience function to get the return type of a function. pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId) -> Ty<'tcx> { - let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output(); + let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().skip_norm_wip().output(); cx.tcx.instantiate_bound_regions_with_erased(ret_ty) } /// Convenience function to get the nth argument type of a function. pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId, nth: usize) -> Ty<'tcx> { - let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth); + let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().skip_norm_wip().input(nth); cx.tcx.instantiate_bound_regions_with_erased(arg) } @@ -2697,7 +2697,7 @@ impl<'tcx> ExprUseNode<'tcx> { Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)), Self::ConstStatic(id) => Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), - ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()), + ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity().skip_norm_wip()), }), Self::Return(id) => { if let Node::Expr(Expr { @@ -2710,7 +2710,7 @@ impl<'tcx> ExprUseNode<'tcx> { FnRetTy::Return(ty) => Some(DefinedTy::Hir(ty)), } } else { - let ty = cx.tcx.fn_sig(id).instantiate_identity().output(); + let ty = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip().output(); Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), ty, @@ -2732,7 +2732,7 @@ impl<'tcx> ExprUseNode<'tcx> { }) .map(|(adt, field_def)| DefinedTy::Mir { def_site_def_id: Some(adt.did()), - ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()), + ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity().skip_norm_wip()), }), _ => None, }, @@ -3221,7 +3221,7 @@ pub fn get_path_from_caller_to_method_type<'tcx>( match assoc_item.container { rustc_ty::AssocContainer::Trait => get_path_to_callee(tcx, from, def_id), rustc_ty::AssocContainer::InherentImpl | rustc_ty::AssocContainer::TraitImpl(_) => { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); get_path_to_ty(tcx, from, ty, args) }, } @@ -3237,7 +3237,7 @@ fn get_path_to_ty<'tcx>(tcx: TyCtxt<'tcx>, from: LocalDefId, ty: Ty<'tcx>, args: | rustc_ty::RawPtr(_, _) | rustc_ty::Ref(..) | rustc_ty::Slice(_) - | rustc_ty::Tuple(_) => format!("<{}>", EarlyBinder::bind(ty).instantiate(tcx, args)), + | rustc_ty::Tuple(_) => format!("<{}>", EarlyBinder::bind(ty).instantiate(tcx, args).skip_norm_wip()), _ => ty.to_string(), } } @@ -3417,7 +3417,7 @@ pub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) - // actually have type adjustments. match expr.kind { ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) if let Some(def_id) = fn_def_id(cx, expr) => { - let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); if !fn_sig.output().skip_binder().has_type_flags(TypeFlags::HAS_TY_PARAM) { return false; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 62eddd20b7269..8f7a140e91a86 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -50,7 +50,7 @@ pub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Ms // impl trait is gone in MIR, so check the return type manually check_ty( cx, - cx.tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(), + cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().output().skip_binder(), body.local_decls.iter().next().unwrap().source_info.span, msrv, )?; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 641c6684a0bd1..ff7e67422bc50 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -891,7 +891,7 @@ impl<'tcx> DerefDelegate<'_, 'tcx> { .cx .typeck_results() .type_dependent_def_id(parent_expr.hir_id) - .map(|did| self.cx.tcx.fn_sig(did).instantiate_identity().skip_binder()) + .map(|did| self.cx.tcx.fn_sig(did).instantiate_identity().skip_norm_wip().skip_binder()) { std::iter::once(receiver) .chain(call_args.iter()) diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index ac807c0382fef..0126364437140 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -22,6 +22,7 @@ use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg, GenericArgKind, GenericArgsRef, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, + Unnormalized, }; use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span, Symbol}; @@ -110,7 +111,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for (predicate, _span) in cx.tcx.explicit_item_self_bounds(def_id).iter_identity_copied() { + for (predicate, _span) in cx.tcx.explicit_item_self_bounds(def_id).iter_identity_copied().map(Unnormalized::skip_normalization) { match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through // and check substitutions to find `U`. @@ -605,7 +606,7 @@ impl<'tcx> ExprFnSig<'tcx> { /// If the expression is function like, get the signature for it. pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option> { if let Res::Def(DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn, id) = expr.res(cx) { - Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate_identity(), Some(id))) + Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip(), Some(id))) } else { ty_sig(cx, cx.typeck_results().expr_ty_adjusted(expr).peel_refs()) } @@ -623,7 +624,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), + ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs).skip_norm_wip(), Some(id))), ty::Alias(AliasTy { kind: ty::Opaque { def_id }, args, @@ -631,7 +632,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option sig_from_bounds( cx, ty, - cx.tcx.item_self_bounds(def_id).iter_instantiated(cx.tcx, args), + cx.tcx.item_self_bounds(def_id).iter_instantiated(cx.tcx, args).map(Unnormalized::skip_normalization), cx.tcx.opt_parent(def_id), ), ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)), @@ -657,7 +658,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { + ) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)) { Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty), _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)), }, @@ -715,8 +716,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx - .explicit_item_bounds(ty.kind.def_id()) - .iter_instantiated_copied(cx.tcx, ty.args) + .explicit_item_bounds(ty.kind.def_id()).iter_instantiated_copied(cx.tcx, ty.args).map(Unnormalized::skip_normalization) { match pred.kind().skip_binder() { ty::ClauseKind::Trait(p) @@ -764,7 +764,7 @@ impl core::ops::Add for EnumValue { /// Attempts to read the given constant as though it were an enum value. pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { - match tcx.type_of(id).instantiate_identity().kind() { + match tcx.type_of(id).instantiate_identity().skip_norm_wip().kind() { ty::Int(_) => Some(EnumValue::Signed(value.to_int(value.size()))), ty::Uint(_) => Some(EnumValue::Unsigned(value.to_uint(value.size()))), _ => None, @@ -886,7 +886,7 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option< Some((adt, adt.variant_with_id(var_id))) }, Res::SelfCtor(id) => { - let adt = cx.tcx.type_of(id).instantiate_identity().ty_adt_def().unwrap(); + let adt = cx.tcx.type_of(id).instantiate_identity().skip_norm_wip().ty_adt_def().unwrap(); Some((adt, adt.non_enum_variant())) }, _ => None, @@ -1066,8 +1066,7 @@ pub fn make_normalized_projection<'tcx>( ); return None; } - match tcx - .try_normalize_erasing_regions(typing_env, Ty::new_projection_from_args(tcx, ty.kind.def_id(), ty.args)) + match tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(Ty::new_projection_from_args(tcx, ty.kind.def_id(), ty.args))) { Ok(ty) => Some(ty), Err(e) => { @@ -1173,7 +1172,7 @@ impl<'tcx> InteriorMut<'tcx> { ty::Alias(AliasTy { kind: ty::Projection { .. }, .. - }) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) { + }) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)) { Ok(normalized_ty) if ty != normalized_ty => self.interior_mut_ty_chain_inner(cx, normalized_ty, depth), _ => None, }, @@ -1319,7 +1318,7 @@ pub fn option_arg_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>) -> bool { fn normalize_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty) + cx.tcx.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty)).unwrap_or(ty) } /// Check if `ty` contains mutable references or equivalent, which includes: diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index eadb07a11be02..5d8d30b910955 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -249,7 +249,7 @@ fn path_segment_certainty( let certainty = lhs.join_clearing_def_ids(rhs); if resolves_to_type { if let DefKind::TyAlias = cx.tcx.def_kind(def_id) { - adt_def_id(cx.tcx.type_of(def_id).instantiate_identity()) + adt_def_id(cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()) .map_or(certainty, |def_id| certainty.with_def_id(def_id)) } else { certainty.with_def_id(def_id) diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 15ad967657de0..579c9e1165d43 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -170,8 +170,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { { let fn_sig = this.tcx.instantiate_bound_regions_with_erased( this.tcx - .fn_sig(instance.def_id()) - .instantiate(*this.tcx, instance.args), + .fn_sig(instance.def_id()).instantiate(*this.tcx, instance.args).skip_norm_wip(), ); let fn_ptr = crate::shims::native_lib::build_libffi_closure(this, fn_sig)?; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 566a775b90108..a59ce648985c2 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1381,7 +1381,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { panic!("extern_statics cannot contain wildcards") }; let info = ecx.get_alloc_info(alloc_id); - let def_ty = ecx.tcx.type_of(def_id).instantiate_identity(); + let def_ty = ecx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip(); let extern_decl_layout = ecx.tcx.layout_of(ecx.typing_env().as_query_input(def_ty)).unwrap(); if extern_decl_layout.size != info.size || extern_decl_layout.align.abi != info.align {