diff --git a/append_method.yaml b/append_method.yaml new file mode 100644 index 0000000000000..31efa8838d5f5 --- /dev/null +++ b/append_method.yaml @@ -0,0 +1,129 @@ +id: append-method-call + +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate($A1, $A2) +# fix: $OBJ.instantiate($A1, $A2).skip_normalization() + +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate_identity() +# fix: $OBJ.instantiate_identity().skip_normalization() +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate_identity($A) +# fix: $OBJ.instantiate_identity($A).skip_normalization() +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate_own($A1, $A2) +# fix: $OBJ.instantiate_own($A1, $A2).map(Unnormalized::skip_normalization) +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate_own_identity() +# fix: $OBJ.instantiate_own_identity().map(Unnormalized::skip_normalization) +# rule: + # kind: call_expression + # pattern: $OBJ.iter_instantiated($A1, $A2) +# fix: $OBJ.iter_instantiated($A1, $A2).map(Unnormalized::skip_normalization) +# rule: + # kind: call_expression + # pattern: $OBJ.iter_identity() +# fix: $OBJ.iter_identity().map(Unnormalized::skip_normalization) + +# rule: + # kind: call_expression + # pattern: $OBJ.iter_identity_copied() +# fix: $OBJ.iter_identity_copied().map(Unnormalized::skip_normalization) +# rule: + # kind: call_expression + # pattern: $OBJ.iter_instantiated_copied($A1, $A2) +# fix: $OBJ.iter_instantiated_copied($A1, $A2).map(Unnormalized::skip_normalization) + +# rule: + # kind: call_expression + # pattern: $OBJ.type_of($A1).instantiate($A2, $A3) +# fix: $OBJ.type_of($A1).instantiate($A2, $A3).uncertain_skip() +# rule: + # kind: call_expression + # pattern: $OBJ.fn_sig($A1).instantiate($A2, $A3) +# fix: $OBJ.fn_sig($A1).instantiate($A2, $A3).uncertain_skip() +# +# normalization. +# rule: + # kind: call_expression + # pattern: $OBJ.normalize_erasing_regions($A1, $A2) +# fix: $OBJ.normalize_erasing_regions($A1, Unnormalized::new($A2)) + +# rule: + # kind: call_expression + # pattern: $OBJ.try_normalize_erasing_regions($A1, $A2) +# fix: $OBJ.try_normalize_erasing_regions($A1, Unnormalized::new($A2)) + +# rule: + # kind: call_expression + # pattern: wfcx.deeply_normalize($SPAN, $A2, $V) +# fix: wfcx.deeply_normalize($SPAN, $A2, Unnormalized::new($V)) +# +# rule: + # kind: call_expression + # pattern: $OBJ.normalize($SPAN, $A2, $V) +# fix: $OBJ.normalize($SPAN, $A2, Unnormalized::new($V)) +# borrowck normalization +# rule: + # kind: call_expression + # pattern: $OBJ.normalize($A1, $A2) +# fix: $OBJ.normalize(Unnormalized::new($A1), $A2) +# rule: + # kind: call_expression + # pattern: $OBJ.deeply_normalize($A1, $A2) +# fix: $OBJ.deeply_normalize(Unnormalized::new($A1), $A2) + +# rule: + # kind: call_expression + # pattern: DeeplyNormalize { value: $V } +# fix: DeeplyNormalize { value: Unnormalized::new($V), tcx: PhantomData } + +# uncertain skip iter +# rule: + # kind: call_expression + # pattern: $OBJ.iter_instantiated_copied($A1, $A2) +# fix: $OBJ.iter_instantiated_copied($A1, $A2).map(Unnormalized::uncertain_skip) + + +# rule: + # kind: call_expression + # pattern: $OBJ.ty($A1, args) +# fix: $OBJ.ty($A1, args).uncertain_skip() +# rule: + # kind: call_expression + # pattern: ty::EarlyBinder::bind($A1).instantiate($A2, $A3) +# fix: ty::EarlyBinder::bind($A1).instantiate($A2, $A3).uncertain_skip() + +# rule: + # kind: call_expression + # pattern: $OBJ.normalize($A1, $A2, $A3) +# fix: ocx.structurally_normalize_ty($A1, $A2, Unnormalized::new($A3)) +# +# rule: + # kind: call_expression + # pattern: $OBJ.instantiate_identity().skip_normalization() +# fix: $OBJ.instantiate_identity() +rule: + kind: call_expression + # pattern: $OBJ.instantiate($A1, $A2).skip_normalization() + pattern: $OBJ.instantiate($$$ARGS) +# fix: $OBJ.instantiate($A1, $A2) +# rule: + # kind: call_expression + # pattern: $OBJ.iter_identity().map(Unnormalized::skip_normalization) +# fix: $OBJ.iter_identity() +# rule: + # kind: call_expression + # pattern: $OBJ.iter_instantiated_copied($A1, $A2).map(Unnormalized::skip_normalization) +# fix: $OBJ.iter_instantiated_copied($A1, $A2) +# rule: + # kind: call_expression + # pattern: $OBJ.iter_instantiated($A1, $A2).map(Unnormalized::skip_normalization) +# fix: $OBJ.iter_instantiated($A1, $A2) + +language: Rust diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b8eefa4dd0714..51a30a5b5f407 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -472,8 +472,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // The move occurred as one of the arguments to a function call. Is that // argument generic? `def_id` can't be a closure here, so using `fn_sig` is fine let arg_param = if self.infcx.tcx.def_kind(def_id).is_fn_like() - && let sig = - self.infcx.tcx.fn_sig(def_id).instantiate_identity().skip_binder() + && let sig = self + .infcx + .tcx + .fn_sig(def_id) + .instantiate_identity() + .skip_normalization() + .skip_binder() && let Some(arg_ty) = sig.inputs().get(pos + offset) && let ty::Param(arg_param) = arg_ty.kind() { @@ -685,7 +690,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { place_span: Span, ) -> Option { let tcx = self.infcx.tcx; - let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_binder(); + let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_normalization().skip_binder(); let clauses = tcx.predicates_of(callee_did); let generic_args = match call_expr.kind { @@ -703,7 +708,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // First, is there at least one method on one of `param`'s trait bounds? // This keeps us from suggesting borrowing the argument to `mem::drop`, e.g. - if !clauses.instantiate_identity(tcx).predicates.iter().any(|clause| { + if !clauses.instantiate_identity(tcx).skip_normalization().predicates.iter().any(|clause| { clause.as_trait_clause().is_some_and(|tc| { tc.self_ty().skip_binder().is_param(param.index) && tc.polarity() == ty::PredicatePolarity::Positive @@ -729,8 +734,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { )); let can_subst = |ty: Ty<'tcx>| { // Normalize before comparing to see through type aliases and projections. - let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args); - let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args); + let old_ty = + ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args).skip_normalization(); + let new_ty = + ty::EarlyBinder::bind(ty).instantiate(tcx, new_args).skip_normalization(); if let Ok(old_ty) = tcx.try_normalize_erasing_regions( self.infcx.typing_env(self.infcx.param_env), old_ty, @@ -754,21 +761,23 @@ 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)| { - // 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; - } - self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( - tcx, - ObligationCause::dummy(), - self.infcx.param_env, - clause, - )) - }) + clauses.instantiate(tcx, new_args).skip_normalization().predicates.iter().all( + |&(mut 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; + } + self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( + tcx, + ObligationCause::dummy(), + self.infcx.param_env, + clause, + )) + }, + ) }) { let place_desc = if let Some(desc) = self.describe_place(moved_place) { format!("`{desc}`") @@ -4153,11 +4162,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_normalization(); 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_normalization(), ), _ => None, } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 86d7119639a3f..133e0e0e4a7a3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1366,9 +1366,16 @@ 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_normalization() + .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 +1452,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_normalization() + .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..c958329a3ee33 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -627,12 +627,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::ExprKind::Call(callee, _) => { let ty = typeck_result.node_type_opt(callee.hir_id)?; let ty::FnDef(fn_def_id, args) = *ty.kind() else { return None }; - tcx.predicates_of(fn_def_id).instantiate(tcx, args) + tcx.predicates_of(fn_def_id).instantiate(tcx, args).skip_normalization() } hir::ExprKind::MethodCall(..) => { let (_, method) = typeck_result.type_dependent_def(parent.hir_id)?; let args = typeck_result.node_args(parent.hir_id); - tcx.predicates_of(method).instantiate(tcx, args) + tcx.predicates_of(method).instantiate(tcx, args).skip_normalization() } _ => return None, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_types.rs index 31890381fd5e3..a585c000d3fb7 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, opaque.args) + .map(Unnormalized::skip_normalization) { 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..a8cbeb1dfae6b 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_normalization() }; 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_normalization(); 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_normalization().kind() else { return; }; @@ -1143,7 +1144,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } }); - let preds = tcx.predicates_of(method_def_id).instantiate(tcx, args); + let preds = tcx.predicates_of(method_def_id).instantiate(tcx, args).skip_normalization(); let ocx = ObligationCtxt::new(&self.infcx); ocx.register_obligations(preds.iter().map(|(pred, span)| { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 9f65052643e5a..df7f9dc8f14d6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -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_normalization(); 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_normalization(), + |r| r.kind() == ty::ReEarlyParam(region), + ); Some(RegionName { name: self.synthesize_region_name(), @@ -1056,6 +1056,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { .tcx .predicates_of(self.body.source.def_id()) .instantiate_identity(self.infcx.tcx) + .skip_normalization() .predicates; if let Some(upvar_index) = self 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..f4c17d8b7d38e 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -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_normalization(), + |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); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0b7b4e01e7523..c91a5f519505a 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_normalization(); let normalized_ty = self.normalize(unnormalized_ty, locations); let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); @@ -1787,7 +1788,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() { - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); + let instantiated_predicates = + tcx.predicates_of(def_id).instantiate(tcx, args).skip_normalization(); self.normalize_and_prove_instantiated_predicates( def_id, instantiated_predicates, @@ -2435,7 +2437,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let (def_id, instantiated_predicates) = match *aggregate_kind { AggregateKind::Adt(adt_did, _, args, _, _) => { - (adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args)) + (adt_did, tcx.predicates_of(adt_did).instantiate(tcx, args).skip_normalization()) } // For closures, we have some **extra requirements** we @@ -2521,7 +2523,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - tcx.predicates_of(def_id).instantiate(tcx, args) + tcx.predicates_of(def_id).instantiate(tcx, args).skip_normalization() } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index e96c6c7c56f9b..41aa030d67543 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -585,7 +585,8 @@ 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_normalization(); debug!("defining_ty (pre-replacement): {:?}", defining_ty); @@ -780,7 +781,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_normalization(); let sig = indices.fold_to_region_vids(tcx, sig); let inputs_and_output = sig.inputs_and_output(); @@ -804,7 +805,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_normalization(); // The signature needs to follow the order [input_tys, va_list_ty, output_ty] return inputs_and_output.map_bound(|tys| { @@ -822,7 +824,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_normalization(); let ty = indices.fold_to_region_vids(tcx, ty); ty::Binder::dummy(tcx.mk_type_list(&[ty])) @@ -835,7 +837,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::GlobalAsm(def_id) => { - ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) + ty::Binder::dummy(tcx.mk_type_list(&[ + tcx.type_of(def_id).instantiate_identity().skip_normalization(), + ])) } }; @@ -974,7 +978,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_normalization(); match *ty.kind() { ty::Closure(_, args) => args.as_closure().sig().bound_vars(), ty::CoroutineClosure(_, args) => { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 3e600914d6f42..f1702c9360560 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -824,9 +824,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_normalization(), + ), _ => unreachable!(), }; assert!(!fn_sig.c_variadic); diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index a45f1124f0af4..c42ef400571fa 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -384,7 +384,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { return None; } - let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args); + let const_conditions = + tcx.const_conditions(callee).instantiate(tcx, callee_args).skip_normalization(); if const_conditions.is_empty() { return None; } diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 3f4527a8750b6..cc1377d358269 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_normalization(); 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_normalization() } } } 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 ccfdf571fb27c..e25488978cdc7 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,9 @@ 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_normalization(), + )?; let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?; trace!( diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 4e7c8310007b8..1409feff49531 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_normalization(); 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/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index c839603160310..7dca0bd9dd5c2 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_normalization().kind() + else { // Could be `ty::Error`. return Ok(()); }; diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index d86bf4cc4e4f9..e44a204d2777a 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_normalization(); match self_ty.kind() { ty::Adt(adt_def, adt_to_impl_args) => { @@ -206,16 +206,23 @@ 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_normalization(); 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_normalization() + .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"); - for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) { + for (clause, span) in + tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args).skip_normalization() + { let normalize_cause = traits::ObligationCause::misc(span, impl_def_id); let pred = ocx.normalize(&normalize_cause, adt_env, clause); let cause = traits::ObligationCause::new( diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b55506117c1dc..41ac309a81991 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}; @@ -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_normalization(); 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_normalization().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_normalization(); 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_normalization) { 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_normalization(); 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_normalization().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_normalization(); 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_normalization().def_id, + )); if res.is_ok() { // Checking this only makes sense if the all trait impls satisfy basic @@ -920,7 +921,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().predicates_of(def_id); res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_normalization(); let ty_span = tcx.ty_span(def_id); let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into()); @@ -952,7 +953,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().predicates_of(def_id); check_type_alias_type_params_are_used(tcx, def_id); - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_normalization(); let span = tcx.def_span(def_id); if tcx.type_alias_is_lazy(def_id) { res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { @@ -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_normalization(); // 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_normalization(), ); } 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_normalization(); 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_normalization(); 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_normalization(), ident ) } else { @@ -1662,7 +1665,9 @@ 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_normalization().kind() + { if def.is_struct() || def.is_union() { if def.repr().align.is_some() { return Some(vec![(def.did(), DUMMY_SP)]); @@ -2024,7 +2029,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_normalization(); 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 29213058d1d5e..afbb0007226c1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -72,17 +72,19 @@ 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_normalization(); 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_normalization(), ); let external_impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_external_impl_sig); debug!(?external_impl_sig); 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 c4ec27e07124f..ff151c8ef148b 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_normalization(); debug!(?impl_trait_ref); match impl_item.kind { @@ -213,9 +214,13 @@ 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 = + impl_predicates.instantiate_identity(tcx).skip_normalization().predicates; 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(Unnormalized::skip_normalization) + .map(|(predicate, _)| predicate), ); let is_conditionally_const = tcx.is_conditionally_const(impl_m.def_id); @@ -225,9 +230,12 @@ fn compare_method_predicate_entailment<'tcx>( hybrid_preds.extend( tcx.const_conditions(impl_def_id) .instantiate_identity(tcx) + .skip_normalization() .into_iter() .chain( - tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args), + tcx.const_conditions(trait_m.def_id) + .instantiate_own(tcx, trait_to_impl_args) + .map(Unnormalized::skip_normalization), ) .map(|(trait_ref, _)| { trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) @@ -266,7 +274,8 @@ 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(Unnormalized::skip_normalization); 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); @@ -290,8 +299,10 @@ 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(Unnormalized::skip_normalization) { let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); @@ -327,14 +338,15 @@ 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_normalization(), ); let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id); let impl_sig = ocx.normalize(&norm_cause, param_env, 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_normalization(); 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, @@ -463,8 +475,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_normalization(); // 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)?; @@ -491,8 +505,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let hybrid_preds = tcx .predicates_of(impl_m.container_id(tcx)) .instantiate_identity(tcx) + .skip_normalization() .into_iter() - .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args)) + .chain( + tcx.predicates_of(trait_m.def_id) + .instantiate_own(tcx, trait_to_impl_args) + .map(Unnormalized::skip_normalization), + ) .map(|(clause, _)| clause); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = traits::normalize_param_env_or_error( @@ -510,7 +529,10 @@ 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(Unnormalized::skip_normalization); 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); @@ -535,7 +557,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( 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_normalization(), ), ); impl_sig.error_reported()?; @@ -549,7 +571,7 @@ 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_normalization(), ) .fold_with(&mut collector); @@ -838,6 +860,7 @@ where .cx() .explicit_item_bounds(def_id) .iter_instantiated_copied(self.cx(), proj.args) + .map(Unnormalized::skip_normalization) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( @@ -1251,11 +1274,12 @@ 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_normalization(); 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_normalization(); let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig); let ocx = ObligationCtxt::new(&infcx); @@ -1441,7 +1465,9 @@ fn find_region_in_predicates<'tcx>( def_id: DefId, early_bound_region: ty::Region<'tcx>, ) -> Option { - for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) { + for (pred, span) in + tcx.explicit_predicates_of(def_id).instantiate_identity(tcx).skip_normalization() + { if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() { return Some(span); } @@ -1507,7 +1533,8 @@ 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_normalization().input(0); let (infcx, param_env) = tcx .infer_ctxt() .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id)); @@ -2110,7 +2137,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_normalization() ) } Type { .. } => format!("{prefix} type parameter"), @@ -2204,9 +2231,10 @@ fn compare_const_predicate_entailment<'tcx>( // Create a parameter environment that represents the implementation's // associated const. - let impl_ty = tcx.type_of(impl_ct_def_id).instantiate_identity(); + let impl_ty = tcx.type_of(impl_ct_def_id).instantiate_identity().skip_normalization(); - let trait_ty = tcx.type_of(trait_ct.def_id).instantiate(tcx, trait_to_impl_args); + let trait_ty = + tcx.type_of(trait_ct.def_id).instantiate(tcx, trait_to_impl_args).skip_normalization(); let code = ObligationCauseCode::CompareImplItem { impl_item_def_id: impl_ct_def_id, trait_item_def_id: trait_ct.def_id, @@ -2220,10 +2248,12 @@ fn compare_const_predicate_entailment<'tcx>( // The predicates declared by the impl definition, the trait and the // associated const in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ct_predicates.parent.unwrap()); - let mut hybrid_preds = impl_predicates.instantiate_identity(tcx).predicates; + let mut hybrid_preds = + impl_predicates.instantiate_identity(tcx).skip_normalization().predicates; hybrid_preds.extend( trait_ct_predicates .instantiate_own(tcx, trait_to_impl_args) + .map(Unnormalized::skip_normalization) .map(|(predicate, _)| predicate), ); @@ -2237,7 +2267,8 @@ 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(Unnormalized::skip_normalization); 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); @@ -2334,7 +2365,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(Unnormalized::skip_normalization); // 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. @@ -2350,10 +2382,12 @@ 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 = + impl_predicates.instantiate_identity(tcx).skip_normalization().predicates; hybrid_preds.extend( trait_ty_predicates .instantiate_own(tcx, trait_to_impl_args) + .map(Unnormalized::skip_normalization) .map(|(predicate, _)| predicate), ); debug!(?hybrid_preds); @@ -2368,9 +2402,12 @@ fn compare_type_predicate_entailment<'tcx>( hybrid_preds.extend( tcx.const_conditions(impl_ty_predicates.parent.unwrap()) .instantiate_identity(tcx) + .skip_normalization() .into_iter() .chain( - tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args), + tcx.const_conditions(trait_ty.def_id) + .instantiate_own(tcx, trait_to_impl_args) + .map(Unnormalized::skip_normalization), ) .map(|(trait_ref, _)| { trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) @@ -2403,8 +2440,10 @@ 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(Unnormalized::skip_normalization); 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); @@ -2510,12 +2549,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_normalization) + .map(|(concrete_ty_bound, span)| { debug!(?concrete_ty_bound); traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) - }, - ), + }), ) .collect(); @@ -2525,6 +2565,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_normalization) .map(|(c, span)| { traits::Obligation::new( tcx, @@ -2700,8 +2741,10 @@ fn param_env_with_gat_bounds<'tcx>( // we want ::Y to normalize to S. This is valid because we are // 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); + let normalize_impl_ty = tcx + .type_of(impl_ty.def_id) + .instantiate(tcx, normalize_impl_ty_args) + .skip_normalization(); 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 f0f15f5e98e8f..0d65005d38912 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_normalization(); 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_normalization(), ); 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_normalization(); // 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_normalization), ); 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_normalization), )); pairs.push((trait_projection, impl_opaque)); @@ -135,8 +141,13 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( let hybrid_preds = tcx .predicates_of(impl_def_id) .instantiate_identity(tcx) + .skip_normalization() .into_iter() - .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args)) + .chain( + tcx.predicates_of(trait_m.def_id) + .instantiate_own(tcx, trait_m_to_impl_m_args) + .map(Unnormalized::skip_normalization), + ) .map(|(clause, _)| clause); 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()); @@ -267,6 +278,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitCollector<'tcx> { .tcx .explicit_item_bounds(def_id) .iter_instantiated_copied(self.tcx, proj.args) + .map(Unnormalized::skip_normalization) { pred.visit_with(self); } @@ -320,6 +332,7 @@ fn report_mismatched_rpitit_signature<'tcx>( let Some(future_output_ty) = tcx .explicit_item_bounds(future_ty_def_id) .iter_instantiated_copied(tcx, future_ty.args) + .map(Unnormalized::skip_normalization) .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..3806af89c58a1 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -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_normalization(); 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_normalization(); if !matches!(hir_type.kind(), ty::FnDef(..)) { span_bug!(sp, "main has a non-function type: found `{}`", hir_type); } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 58454cfc489c6..69b6d55f16c39 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_normalization(); (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..b4220863a6c92 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_normalization(), )); 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_normalization) .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_normalization(), ), assoc.ident(tcx), - tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), + tcx.predicates_of(assoc.def_id) + .instantiate_own(tcx, args) + .map(Unnormalized::skip_normalization), 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(Unnormalized::skip_normalization), 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_normalization(); let val = tcx .infer_ctxt() .build(TypingMode::non_body_analysis()) @@ -647,7 +653,7 @@ pub fn check_function_signature<'tcx>( let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(infcx); - let actual_sig = tcx.fn_sig(fn_id).instantiate_identity(); + let actual_sig = tcx.fn_sig(fn_id).instantiate_identity().skip_normalization(); let norm_cause = ObligationCause::misc(cause.span, local_id); let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index c7b87db5971fa..77350f40b8b74 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; @@ -416,7 +416,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_normalization(), ); gather_gat_bounds( tcx, @@ -446,6 +446,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_normalization) .collect::>(), &FxIndexSet::default(), gat_def_id, @@ -840,7 +841,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_normalization(); let span = tcx.def_span(param.def_id); let def_id = param.def_id.expect_local(); @@ -963,7 +964,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_normalization() } }; @@ -971,7 +972,7 @@ pub(crate) fn check_associated_item( match item.kind { ty::AssocKind::Const { .. } => { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_normalization(); let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); @@ -993,7 +994,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_normalization(); 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); @@ -1004,7 +1005,7 @@ pub(crate) fn check_associated_item( check_associated_type_bounds(wfcx, item, span) } if item.defaultness(tcx).has_value() { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_normalization(); let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); } @@ -1055,7 +1056,7 @@ fn check_type_defn<'tcx>( let ty = wfcx.deeply_normalize( hir_ty.span, None, - tcx.type_of(field.did).instantiate_identity(), + tcx.type_of(field.did).instantiate_identity().skip_normalization(), ); wfcx.register_wf_obligation( hir_ty.span, @@ -1082,7 +1083,8 @@ 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_normalization(); let ty = tcx.erase_and_anonymize_regions(ty); assert!(!ty.has_infer()); ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env)) @@ -1101,7 +1103,7 @@ fn check_type_defn<'tcx>( let ty = wfcx.normalize( hir_ty.span, None, - tcx.type_of(field.did).instantiate_identity(), + tcx.type_of(field.did).instantiate_identity().skip_normalization(), ); wfcx.register_bound( traits::ObligationCause::new( @@ -1189,15 +1191,18 @@ 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_normalization) + .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 +1215,7 @@ fn check_item_fn( enter_wf_checking_ctxt(tcx, def_id, |wfcx| { check_eiis(tcx, def_id); - let sig = tcx.fn_sig(def_id).instantiate_identity(); + let sig = tcx.fn_sig(def_id).instantiate_identity().skip_normalization(); check_fn_or_method(wfcx, sig, decl, def_id); Ok(()) }) @@ -1323,7 +1328,7 @@ pub(super) fn check_type_const<'tcx>( ); if has_value { - let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); + let raw_ct = tcx.const_of_item(def_id).instantiate_identity().skip_normalization(); let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct); wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into()); @@ -1349,7 +1354,8 @@ fn check_impl<'tcx>( // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). - let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity(); + let trait_ref = + tcx.impl_trait_ref(item.owner_id).instantiate_identity().skip_normalization(); // 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)?; @@ -1388,8 +1394,10 @@ fn check_impl<'tcx>( // Ensure that the `[const]` where clauses of the trait hold for the impl. if tcx.is_conditionally_const(item.owner_id.def_id) { - for (bound, _) in - tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args) + for (bound, _) in tcx + .const_conditions(trait_ref.def_id) + .instantiate(tcx, trait_ref.args) + .skip_normalization() { let bound = wfcx.normalize( item.span, @@ -1413,7 +1421,8 @@ 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_normalization(); let self_ty = wfcx.deeply_normalize( item.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), @@ -1448,7 +1457,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_normalization) + { // 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. @@ -1475,15 +1488,18 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: | ty::ConstKind::Bound(_, _) => unreachable!(), 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) - } + ty::ConstKind::Unevaluated(uv) => infcx + .tcx + .type_of(uv.def) + .instantiate(infcx.tcx, uv.args) + .skip_normalization(), 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_normalization(); if !ct_ty.has_param() && !param_ty.has_param() { let cause = traits::ObligationCause::new( tcx.def_span(param.def_id), @@ -1512,7 +1528,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_normalization) // ... and it's not a dependent default, ... && !default.has_param() { @@ -1553,7 +1569,8 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args); + let instantiated_pred = + ty::EarlyBinder::bind(pred).instantiate(tcx, args).skip_normalization(); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. if instantiated_pred.has_non_region_param() @@ -1587,7 +1604,7 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: Obligation::new(tcx, cause, wfcx.param_env, pred) }); - let predicates = predicates.instantiate_identity(tcx); + let predicates = predicates.instantiate_identity(tcx).skip_normalization(); let assoc_const_obligations: Vec<_> = predicates .predicates @@ -1601,7 +1618,8 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: 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_normalization(); ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty) }) }) @@ -1740,7 +1758,7 @@ 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_normalization(); let sig = tcx.liberate_late_bound_regions(method.def_id, sig); let sig = wfcx.normalize(DUMMY_SP, loc, sig); @@ -2083,6 +2101,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_normalization() .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) { continue; @@ -2114,7 +2133,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_normalization() + .visit_with(self)?; } } } @@ -2235,12 +2258,19 @@ 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_normalization() + .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) - } + DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => self + .tcx + .type_of(def_id) + .instantiate_identity() + .skip_normalization() + .visit_with(self), _ => ControlFlow::Continue(()), } } @@ -2440,8 +2470,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_normalization() + .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..a250e55cb7c33 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -73,7 +73,8 @@ 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_normalization().self_ty().kind() + { ty::Adt(def, _) if def.did().is_local() => return Ok(()), ty::Error(_) => return Ok(()), _ => {} @@ -93,7 +94,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_normalization().self_ty(); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); let param_env = tcx.param_env(impl_did); @@ -142,7 +143,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_normalization().self_ty(); debug!("visit_implementation_of_unpin: self_type={:?}", self_type); let span = tcx.def_span(impl_did); @@ -175,7 +176,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_normalization().self_ty(); assert!(!self_type.has_escaping_bound_vars()); let param_env = tcx.param_env(impl_did); @@ -259,7 +260,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_normalization(); debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); @@ -344,7 +345,8 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() .iter_enumerated() .filter_map(|(i, field)| { // Ignore PhantomData fields - let unnormalized_ty = tcx.type_of(field.did).instantiate_identity(); + let unnormalized_ty = + tcx.type_of(field.did).instantiate_identity().skip_normalization(); if tcx .try_normalize_erasing_regions( ty::TypingEnv::non_body_analysis(tcx, def_a.did()), @@ -445,8 +447,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_normalization(); + let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_normalization(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.args.type_at(1); @@ -564,7 +566,8 @@ pub(crate) fn coerce_unsized_info<'tcx>( let (a, b) = (f.ty(tcx, args_a), f.ty(tcx, args_b)); // Ignore PhantomData fields - let unnormalized_ty = tcx.type_of(f.did).instantiate_identity(); + let unnormalized_ty = + tcx.type_of(f.did).instantiate_identity().skip_normalization(); if tcx .try_normalize_erasing_regions( ty::TypingEnv::non_body_analysis(tcx, def_a.did()), @@ -788,7 +791,11 @@ 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_normalization() + .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..3432f1714b874 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_normalization(); 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 8f83761518bda..6442e804da3c6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -164,7 +164,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_normalization(); 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..d64f737b44d10 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -22,7 +22,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_normalization(); trait_ref.error_reported()?; match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) { @@ -301,7 +301,7 @@ 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_normalization(); let lazily_normalize_ty = |user_ty: Ty<'tcx>| { let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) }; diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 86839e4033034..2b7e200bb75b2 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_normalization(); 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 cfda0300f3f02..f5ecb3685155c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -388,7 +388,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_normalization(); // See comment on doing this operation for `self_ty` let impl_ty = self.tcx.expand_free_alias_tys(impl_ty); @@ -1018,8 +1018,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_normalization(); + let inputs = data + .fields() + .iter() + .map(|f| tcx.type_of(f.def_id).instantiate_identity().skip_normalization()); // 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, @@ -1360,7 +1363,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_normalization(); let is_rustc_reservation = find_attr!(tcx, def_id, RustcReservationImpl(..)); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); @@ -1584,9 +1587,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_normalization(), + ); ty::EarlyBinder::bind(ct) } @@ -1700,9 +1704,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_normalization(), + ); 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 3e9c83b12df0a..14a845493f20b 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -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_normalization(); let span = tcx.def_span(id); tcx.dcx().emit_err(crate::errors::TypeOf { span, ty }); } @@ -32,7 +32,8 @@ 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).skip_normalization().predicates; let span = tcx.def_span(id); let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str()); @@ -47,7 +48,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_normalization(); let span = tcx.def_span(id); let mut diag = tcx.dcx().struct_span_err(span, name); @@ -122,7 +123,8 @@ 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(); + let trait_ref = + tcx.impl_trait_ref(def_id).instantiate_identity().skip_normalization(); if trait_ref.has_non_region_param() { tcx.dcx().span_err( attr_span, @@ -149,7 +151,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) { tcx.vtable_entries(trait_ref) } hir::ItemKind::TyAlias(..) => { - let ty = tcx.type_of(def_id).instantiate_identity(); + let ty = tcx.type_of(def_id).instantiate_identity().skip_normalization(); if ty.has_non_region_param() { tcx.dcx().span_err( attr_span, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index eb005881245ce..1ffe1c059a545 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -559,7 +559,10 @@ 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, projection_ty.args) + self.tcx + .type_of(projection_ty_def_id) + .instantiate(self.tcx, projection_ty.args) + .skip_normalization() } 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 30b1bf411687e..da941352e1513 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -7,7 +7,8 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::find_attr; use rustc_middle::ty::{ - self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, + self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, + Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; @@ -92,8 +93,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(Unnormalized::skip_normalization), + ); // We also install bidirectional outlives predicates for the RPITIT // to keep the duplicates lifetimes from opaque lowering in sync. @@ -118,12 +122,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_normalization().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(Unnormalized::skip_normalization); return ty::GenericPredicates { parent: Some(impl_def_id), @@ -161,8 +168,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_normalization(), + )); } } ItemKind::Trait(_, _, _, _, _, self_bounds, ..) @@ -248,7 +256,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_normalization(); 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 +353,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_normalization(); + let trait_ref = impl_ + .of_trait + .is_some() + .then(|| tcx.impl_trait_ref(def_id).instantiate_identity().skip_normalization()); cgp::setup_constraining_predicates( tcx, &mut predicates, @@ -465,18 +475,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_normalization().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_normalization().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_normalization(); 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 4312d5fa9dddf..dd7b70bc26c31 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_normalization() + .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_normalization) + .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_normalization().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_normalization(), + ); 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..ae94adeddf55a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -182,7 +182,9 @@ 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_normalization() + } Node::ForeignItem(foreign_item) => match foreign_item.kind { ForeignItemKind::Fn(..) => { @@ -204,9 +206,10 @@ 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() - } + VariantData::Unit(..) | VariantData::Struct { .. } => tcx + .type_of(tcx.hir_get_parent_item(hir_id)) + .instantiate_identity() + .skip_normalization(), VariantData::Tuple(_, _, ctor) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, ctor.to_def_id(), args) @@ -356,7 +359,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_normalization() } _ => Ty::new_error_with_message( @@ -418,7 +421,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_normalization() } 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 730288574e762..f63e3073bcee5 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -281,9 +281,11 @@ 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_normalization(), + ), // For trait impl's `sig_id` is always equal to the corresponding trait method. // For inherent methods delegation is not yet supported. @@ -335,7 +337,12 @@ 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_normalization() + .args; assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); @@ -343,7 +350,10 @@ 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_normalization(); tcx.mk_args_from_iter( std::iter::once(ty::GenericArg::from(self_ty)).chain(delegation_args.iter()), @@ -450,7 +460,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_normalization(), + pred.1, + )); } self @@ -539,7 +552,8 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( let caller_sig = tcx.fn_sig(sig_id); if let Err(err) = check_constraints(tcx, def_id, sig_id) { - let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; + let sig_len = + caller_sig.instantiate_identity().skip_normalization().skip_binder().inputs().len() + 1; let err_type = Ty::new_error(tcx, err); return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type)); } @@ -548,7 +562,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( let (mut folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args); let caller_sig = EarlyBinder::bind(caller_sig.skip_binder().fold_with(&mut folder)); - let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_binder(); + let sig = caller_sig.instantiate(tcx, args.as_slice()).skip_normalization().skip_binder(); let sig_iter = sig.inputs().iter().cloned().chain(std::iter::once(sig.output())); tcx.arena.alloc_from_iter(sig_iter) } 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..288a45ba1ccec 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,9 @@ 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_normalization() }); let ty = check_assoc_const_binding_type( self, @@ -851,7 +853,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_normalization()) } } 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..dc6d3f9fd5847 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,9 @@ 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_normalization().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 +513,8 @@ 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_normalization(); let inputs = fn_sig.inputs().skip_binder(); suggestion = vec![( ident.span.with_hi(expr.span.hi()), @@ -728,7 +731,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_normalization(); let note = format!("{title} is defined in an impl for the type `{impl_ty}`"); if let Some(span) = note_span { @@ -782,7 +785,13 @@ 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_normalization() + ) }) .collect::>() .join("\n"); @@ -1786,7 +1795,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_normalization(); 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 0ca57cb50cf25..7bba11602c3a6 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_normalization(); 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 d79f38e097fbd..7e2aeffe14a86 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; @@ -720,7 +721,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_normalization(), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -765,6 +768,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.at(self.span) .type_of(param.def_id) .instantiate(tcx, preceding_args) + .skip_normalization() .into() } else if infer_args { self.lowerer.ty_infer(Some(param), self.span).into() @@ -777,13 +781,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_normalization(); 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_normalization() .into() } else if infer_args { self.lowerer.ct_infer(Some(param), self.span).into() @@ -1165,7 +1171,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id: did }, args); Ty::new_alias(tcx, alias_ty) } else { - tcx.at(span).type_of(did).instantiate(tcx, args) + tcx.at(span).type_of(did).instantiate(tcx, args).skip_normalization() } } @@ -1195,6 +1201,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { || { let trait_refs = predicates .iter_identity_copied() + .map(Unnormalized::skip_normalization) .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) }, @@ -1316,7 +1323,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_normalization() }); let ty = bounds::check_assoc_const_binding_type( self, @@ -1660,7 +1669,9 @@ 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_normalization(), + ); traits::supertraits(tcx, trait_ref) }, AssocItemQSelf::SelfTyAlias, @@ -1893,10 +1904,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_normalization(); let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased); // FIXME: Don't bother dealing with non-lifetime binders here... @@ -2255,7 +2263,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_normalization(); let _ = self.prohibit_generic_args( path.segments.iter(), GenericsArgsErrExtend::SelfTyAlias { def_id, span }, @@ -2564,7 +2572,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_normalization(), + ) }) .collect::>(); @@ -2685,7 +2696,9 @@ 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_normalization(), ) } None => { @@ -2894,7 +2907,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_normalization(); match self.try_lower_anon_const_lit(ty, expr) { Some(v) => v, @@ -3005,7 +3018,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_normalization() } rustc_hir::InferDelegation::Sig(_, idx) => { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); @@ -3592,10 +3605,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_normalization(); 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..faaba6d92acac 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_normalization(); // 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_normalization()); 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_normalization(), + 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_normalization(); // 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_normalization); 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 41af59388f798..fdbc24ded1df1 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,8 @@ 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_normalization(); // 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 +327,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) + .skip_normalization() + .into_iter(), ) .collect(); @@ -339,6 +343,7 @@ fn check_predicates<'tcx>( tcx, tcx.predicates_of(impl2_node.def_id()) .instantiate(tcx, impl2_args) + .skip_normalization() .into_iter() .map(|(c, _s)| c.as_predicate()), ) @@ -373,7 +378,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_normalization().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..25e6b7c0d3f10 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_normalization(); 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_normalization(), tcx.def_span(item_did), &global_inferred_outlives, &mut item_required_predicates, @@ -306,7 +307,10 @@ 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_normalization(); debug!("predicate = {predicate:?}"); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); } @@ -349,7 +353,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_normalization(); 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..4f841276eda0b 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_normalization(); // 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_normalization(), 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_normalization(), self.covariant, ); } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index b9f875a3c629b..fb9b4d33ec5e4 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_normalization) + { 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..3b5136d356c86 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_normalization().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..94c00b7d05b7f 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -542,14 +542,15 @@ 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_normalization(); // Unit testing: function items annotated with // `#[rustc_evaluate_where_clauses]` trigger special output // to let us test the trait evaluation system. if self.has_rustc_attrs && find_attr!(self.tcx, def_id, RustcEvaluateWhereClauses) { let predicates = self.tcx.predicates_of(def_id); - let predicates = predicates.instantiate(self.tcx, args); + let predicates = predicates.instantiate(self.tcx, args).skip_normalization(); for (predicate, predicate_span) in predicates { let obligation = Obligation::new( self.tcx, @@ -947,7 +948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.is_conditionally_const(callee_did) { let q = self.tcx.const_conditions(callee_did); for (idx, (cond, pred_span)) in - q.instantiate(self.tcx, callee_args).into_iter().enumerate() + q.instantiate(self.tcx, callee_args).skip_normalization().into_iter().enumerate() { let cause = self.cause( span, diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 612396858841f..283083356ca24 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_normalization() }); // 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_normalization(); 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..062f8df351751 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_normalization) .map(|(c, s)| (c.as_predicate(), s)), ), ty::Dynamic(object_type, ..) => { @@ -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_normalization) .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, ty::Error(_) => return Some(ret_ty), _ => { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bfc677046e0f4..d5eba353cdece 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}; @@ -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_normalization) + .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 55e6d233f4755..2f7ddc3d77dc8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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_normalization(); } } @@ -2480,7 +2480,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_normalization(); 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 +2593,8 @@ 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_normalization(); let inputs = fn_sig.inputs().skip_binder(); let fields = format!( "({})", @@ -2620,7 +2622,8 @@ 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_normalization(); let inputs = fn_sig.inputs().skip_binder(); let fields = format!( "({})", @@ -3215,7 +3218,11 @@ 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_normalization(); err.span_note( self.tcx.def_span(item.def_id), format!("the candidate is defined in an impl for the type `{impl_ty}`"), @@ -3545,8 +3552,11 @@ 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_normalization(); let cause = self.misc(base_expr.span); // Match the impl self type against the base ty. If this fails, @@ -3575,7 +3585,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }, self.param_env, - self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args), + self.tcx + .predicates_of(impl_def_id) + .instantiate(self.tcx, impl_args) + .skip_normalization(), )); // Normalize the output type, which we can use later on as the diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 5aadf37720d0c..6ac502737110f 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_normalization() && 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 6b8dcf1258d45..dc5dd3737836a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -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_normalization(); // Build new args: [Self, own_args...] let own_args = &args[generics.parent_count..]; tcx.mk_args_from_iter( @@ -431,7 +431,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args: GenericArgsRef<'tcx>, ) -> ty::InstantiatedPredicates<'tcx> { let bounds = self.tcx.predicates_of(def_id); - let result = bounds.instantiate(self.tcx, args); + let result = bounds.instantiate(self.tcx, args).skip_normalization(); let result = self.normalize(span, result); debug!("instantiate_bounds(bounds={:?}, args={:?}) = {:?}", bounds, args, result); result @@ -1133,7 +1133,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_normalization(), ); // Firstly, check that this SelfCtor even comes from the item we're currently @@ -1291,7 +1291,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_normalization(), ) .into(), (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -1311,7 +1312,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_normalization(); } // 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., @@ -1358,7 +1359,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = tcx.type_of(def_id); assert!(!args.has_escaping_bound_vars()); assert!(!ty.skip_binder().has_escaping_bound_vars()); - let ty_instantiated = self.normalize(span, ty.instantiate(tcx, args)); + let ty_instantiated = self.normalize(span, ty.instantiate(tcx, args).skip_normalization()); if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { // In the case of `Foo::method` and `>::method`, if `method` @@ -1366,7 +1367,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // type parameters, which we can infer by unifying the provided `Self` // 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 impl_ty = self.normalize( + span, + tcx.type_of(impl_def_id).instantiate(tcx, args).skip_normalization(), + ); let self_ty = self.normalize(span, self_ty); match self.at(&self.misc(span), self.param_env).eq( DefineOpaqueTypes::Yes, 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..c1567b2915f83 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 @@ -53,6 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .predicates_of(def_id) .instantiate_identity(self.tcx) + .skip_normalization() .predicates .into_iter() .nth(idx) => @@ -64,6 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .const_conditions(def_id) .instantiate_identity(self.tcx) + .skip_normalization() .into_iter() .nth(idx) => { @@ -524,7 +526,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_normalization(), )); } } @@ -552,7 +554,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_normalization(); 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..81e868cfebc8a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1385,7 +1385,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let instantiated = self .tcx .explicit_predicates_of(self.body_id) - .instantiate_identity(self.tcx); + .instantiate_identity(self.tcx) + .skip_normalization(); // FIXME(compiler-errors): This could be problematic if something has two // fn-like predicates with different args, but callable types really never // do that, so it's OK. @@ -1571,8 +1572,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id))); if let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(def_id) - && let ty::Param(_) = - self.tcx.fn_sig(def_id).instantiate_identity().skip_binder().output().kind() + && let ty::Param(_) = self + .tcx + .fn_sig(def_id) + .instantiate_identity() + .skip_normalization() + .skip_binder() + .output() + .kind() && let parent = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id && let Some((output, body_id)) = match self.tcx.hir_node_by_def_id(parent) { hir::Node::Item(hir::Item { @@ -3014,7 +3021,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_normalization(); 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 857713e3295c9..bdccde1bf25e2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -329,7 +329,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { let self_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, self_ty); let impl_args = infcx.fresh_args_for_item(span, impl_); - let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args); + let impl_ty = tcx.type_of(impl_).instantiate(tcx, impl_args).skip_normalization(); let impl_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, impl_ty); // Check that the self types can be related. @@ -338,7 +338,8 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { } // Check whether the impl imposes obligations we have to worry about. - let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_args); + let impl_bounds = + tcx.predicates_of(impl_).instantiate(tcx, impl_args).skip_normalization(); let impl_bounds = ocx.normalize(&ObligationCause::dummy(), self.param_env, impl_bounds); let impl_obligations = traits::predicates_for_generics( |_, _| ObligationCause::dummy(), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index a2f4c57bd442c..d2011ff29b09a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -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_normalization(); // FIXME(compiler-errors): This check is *so* rudimentary if item_ty.has_param() { return false; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index fe8a9a9fb4f73..c4066ccc0152d 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -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_normalization() }; check_abi(tcx, id, span, fn_sig.abi()); @@ -188,7 +188,7 @@ 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_normalization() }; loops::check(tcx, def_id, body); @@ -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_normalization(); 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_normalization()) } 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 ed75609eaecdc..879c9d8d5efc8 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -128,7 +128,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let filler_args = rcvr_args .extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def)); let illegal_sized_bound = self.predicates_require_illegal_sized_bound( - self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_args), + self.tcx + .predicates_of(pick.item.def_id) + .instantiate(self.tcx, filler_args) + .skip_normalization(), ); // Unify the (adjusted) self type with what the method expects. @@ -461,7 +464,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_normalization(), ) .into(), (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { @@ -588,11 +592,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // type/early-bound-regions instantiations performed. There can // be no late-bound regions appearing here. let def_id = pick.item.def_id; - let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args); + let method_predicates = + self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args).skip_normalization(); 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_normalization(); debug!("type scheme instantiated, sig={:?}", sig); let sig = self.instantiate_binder_with_fresh_vars(sig); diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 083e29bff04f7..fbd51ac5ceb22 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -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_normalization(); let fn_sig = self.instantiate_binder_with_fresh_vars( obligation.cause.span, BoundRegionConversionTime::FnCall, @@ -440,7 +440,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // Note that as the method comes from a trait, it should not have // any late-bound regions appearing in its bounds. - let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, args); + let bounds = + self.tcx.predicates_of(def_id).instantiate(self.tcx, args).skip_normalization(); let InferOk { value: bounds, obligations: o } = self.at(&obligation.cause, self.param_env).normalize(bounds); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index c7442373353eb..edbc7b80ab304 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -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_normalization(); let fty = self.instantiate_binder_with_fresh_vars( self.span, BoundRegionConversionTime::FnCall, @@ -1971,7 +1972,11 @@ 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_normalization(); (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); @@ -1987,8 +1992,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { xform_ret_ty = ocx.normalize(cause, self.param_env, 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 = - self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args); + let impl_bounds = self + .tcx + .predicates_of(impl_def_id) + .instantiate(self.tcx, impl_args) + .skip_normalization(); let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds); // Convert the bounds into obligations. ocx.register_obligations(traits::predicates_for_generics( @@ -2557,7 +2565,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_normalization() } else { let args = GenericArgs::for_item(self.tcx, method, |param, _| { let i = param.index as usize; @@ -2575,7 +2583,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } }); - fn_sig.instantiate(self.tcx, args) + fn_sig.instantiate(self.tcx, args).skip_normalization() }; 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 dc5e782bc34f0..f4f9c67f45907 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -478,7 +478,12 @@ 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_normalization(); } } } @@ -1406,7 +1411,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_normalization() != rcvr_ty } (Mode::Path, false, _) => true, @@ -1425,7 +1434,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_normalization() + .to_string(), ), StringPart::normal(format!("`")), ] @@ -1439,7 +1453,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_normalization() ) }) .collect::>() @@ -1534,7 +1552,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_normalization(); 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 +1598,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_normalization(); let inputs = fn_sig.inputs().skip_binder(); suggestion = vec![( replacement_span, @@ -2204,7 +2222,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_normalization(); let fn_sig = self.instantiate_binder_with_fresh_vars( span, BoundRegionConversionTime::FnCall, @@ -2287,8 +2306,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_normalization(); let fn_sig = self.instantiate_binder_with_fresh_vars( item_name.span, BoundRegionConversionTime::FnCall, @@ -2363,7 +2385,12 @@ 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_normalization(); let insertion = match self.tcx.impl_opt_trait_ref(impl_did) { None => String::new(), @@ -2411,6 +2438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx, self.fresh_args_for_item(sugg_span, impl_did), ) + .skip_normalization() .with_replaced_self_ty(self.tcx, rcvr_ty), idx, sugg_span, @@ -2510,6 +2538,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_normalization() .output(); let ret_ty = self.tcx.instantiate_bound_regions_with_erased(ret_ty); let ty::Adt(def, args) = ret_ty.kind() else { @@ -2591,7 +2620,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_normalization(); let target_ty = self .autoderef(sugg_span, rcvr_ty) .silence_errors() @@ -2628,9 +2657,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_normalization(), + ), CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty), }; @@ -2641,7 +2671,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_normalization(); 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 +2856,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_normalization(); let pick = self.lookup_probe_for_diagnostic( item_name, @@ -3492,6 +3525,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .type_of(impl_def_id) .instantiate_identity() + .skip_normalization() .ty_adt_def() .is_some_and(|def| def.did() == adt.did()) }) { @@ -3623,7 +3657,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_normalization().inputs().skip_binder().get(0) && self_ty.is_ref() { let suggested_path = match deref_ty.kind() { @@ -4585,7 +4619,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_normalization(); let imp_simp = simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid); imp_simp.is_some_and(|s| s == simp_rcvr_ty) @@ -4855,8 +4889,13 @@ fn print_disambiguation_help<'tcx>( { let def_kind_descr = tcx.def_kind_descr(item.as_def_kind(), item.def_id); let item_name = item.ident(tcx); - let first_input = - tcx.fn_sig(item.def_id).instantiate_identity().skip_binder().inputs().get(0); + let first_input = tcx + .fn_sig(item.def_id) + .instantiate_identity() + .skip_normalization() + .skip_binder() + .inputs() + .get(0); let (first_arg_type, rcvr_ref) = ( first_input.map(|first| first.peel_refs()), first_input diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs index 18c1bf39a7c13..8b9a5b06e2276 100644 --- a/compiler/rustc_hir_typeck/src/opaque_types.rs +++ b/compiler/rustc_hir_typeck/src/opaque_types.rs @@ -131,7 +131,8 @@ 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_normalization(); self.demand_eqtype(hidden_type.span, expected, hidden_type.ty); } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0cf1998ae28a2..07db76923aee9 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -623,6 +623,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { hidden_ty .ty .instantiate_identity() + .skip_normalization() .visit_with(&mut HasRecursiveOpaque { def_id, seen: Default::default(), @@ -1060,7 +1061,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_normalization().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 29cbbe5a1c9ed..f44c373d65db9 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_normalization(); 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_normalization) + { let predicate = replace_opaques_in(predicate, goals); // Require that the predicate holds for the concrete type. @@ -363,7 +366,10 @@ 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_normalization) + { 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..c1b919ef22cff 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_normalization) .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..69afbd07376c3 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_normalization) .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..8e6029616654a 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_normalization) .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 eadb099a3e1a2..9085bc3b8cdb1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1163,8 +1163,9 @@ 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()), + ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()).as_query_input( + tcx.type_of(def_id).instantiate_identity().skip_normalization(), + ), ); } }); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index af590d98c301c..04fc6d31d34eb 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -467,7 +467,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_normalization(); let outerdef = match impl_ty.kind() { ty::Adt(def, _) => Some(def.did()), ty::Foreign(def_id) => Some(*def_id), @@ -576,7 +576,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_normalization().is_raw_ptr() { return; } } @@ -706,7 +706,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_normalization(), + ) .next() .is_some(); if !has_impl { @@ -1379,7 +1382,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_normalization(); if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) && cx.tcx.features().generic_const_exprs() { diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index d162ae4b77647..a255c0dd34451 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -102,8 +102,9 @@ 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_normalization().kind() + { + ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity().skip_normalization(), 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..9bd77d96bd139 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_normalization(); 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..ccdfff900129b 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_normalization() && 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..58cc10ed90109 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_normalization().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..19be2c33846ae 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -123,7 +123,8 @@ 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_normalization(); debug!( "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}", existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty @@ -297,8 +298,12 @@ 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_normalization(), + tcx.type_of(b_did) + .instantiate(tcx, b_gen_args) + .skip_normalization(), ) }, ) diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs index ae62bfbba2969..1bdd8fa5bc006 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_normalization(); 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 6edf2e9436650..a4dadc5bbf6da 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_normalization(); let mut in_scope_parameters = FxIndexMap::default(); // Populate the in_scope_parameters list first with all of the generics in scope @@ -247,7 +248,11 @@ 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, opaque_ty.args).visit_with(self) + self.tcx + .type_of(def_id) + .instantiate(self.tcx, opaque_ty.args) + .skip_normalization() + .visit_with(self) } else if let ty::Alias(opaque_ty @ ty::AliasTy { kind: ty::Opaque { def_id}, .. }) = *t.kind() && let Some(opaque_def_id) = def_id.as_local() // Don't recurse infinitely on an opaque @@ -413,7 +418,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_normalization) + { clause.visit_with(self) } } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 357aa94feb1ed..ab91b018e2cfc 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -128,7 +128,8 @@ fn has_unstable_into_iter_predicate<'tcx>( let Some(into_iter_fn_def_id) = cx.tcx.lang_items().into_iter_fn() else { return false; }; - let predicates = cx.tcx.predicates_of(callee_def_id).instantiate(cx.tcx, generic_args); + let predicates = + cx.tcx.predicates_of(callee_def_id).instantiate(cx.tcx, generic_args).skip_normalization(); for (predicate, _) in predicates { let Some(trait_pred) = predicate.as_trait_clause() else { continue; @@ -291,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_normalization().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 93f067d09833a..0e1a869116c94 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_normalization) .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/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index b45f92285b81f..71bc81be6eb33 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_normalization) + { infcx.enter_forall(pred.kind(), |predicate| { let ty::ClauseKind::Projection(proj) = predicate else { return; @@ -146,6 +151,7 @@ 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_normalization) { let assoc_pred = assoc_pred.fold_with(proj_replacer); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 2daf2a150354e..c4c009826b55b 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -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_normalization(); let is_1zst = tcx.layout_of(typing_env.as_query_input(field_ty)).is_ok_and(|layout| layout.is_1zst()); !is_1zst @@ -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_normalization(); 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_normalization().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..896ef03bf6510 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -198,7 +198,8 @@ 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_normalization(); if check_arg_for_power_alignment(cx, field_ty) { return true; } @@ -235,7 +236,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_normalization(); if check_arg_for_power_alignment(cx, ty) { cx.emit_span_lint(USES_POWER_ALIGNMENT, field_def.span, UsesPowerAlignment); } @@ -848,7 +849,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_normalization(); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { @@ -880,7 +881,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_normalization(); 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 +895,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_normalization(); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { @@ -1008,7 +1009,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_normalization(), CItemKind::Definition, ); } @@ -1042,7 +1043,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_normalization(), CItemKind::Definition, ); } diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index 5bbe84a51fa2f..948a78c058ac1 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_normalization), + ) + // 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..e566009140ac2 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_normalization() .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_normalization() + .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_normalization(); 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 8bf919dab8e79..a4beadd7454d3 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2174,7 +2174,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_normalization(); 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..c6e0413b8a0b2 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -629,7 +629,8 @@ 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_normalization(); Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ })) } @@ -819,7 +820,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_normalization() + } 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..7846d2b7cddc3 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_normalization().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..e1f81fb06b9c5 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_normalization(); return bac.fold_with(self); } Ok(None) => c, diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index cabe8514ae4be..e0b87199d70b6 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -116,7 +116,11 @@ impl AssocItem { // late-bound regions, and we don't want method signatures to show up // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound // regions just fine, showing `fn(&MyType)`. - tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string() + tcx.fn_sig(self.def_id) + .instantiate_identity() + .skip_normalization() + .skip_binder() + .to_string() } ty::AssocKind::Type { .. } => format!("type {};", self.name()), ty::AssocKind::Const { name, .. } => { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f0707cfbbb40c..6eb110e90c530 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_normalization(), ) } @@ -2763,7 +2764,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_normalization().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..47e821e334586 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) + .skip_normalization() + .predicates + .into_iter(), ) } @@ -362,7 +366,10 @@ 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(Unnormalized::skip_normalization) + .map(|(clause, _)| clause), ) } @@ -415,7 +422,11 @@ 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) + .skip_normalization() + .into_iter() + .map(|(c, _)| c), ) } @@ -424,7 +435,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..148736bda19cf 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -629,7 +629,8 @@ 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_normalization(); 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 +697,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_normalization(), + ), Closure(..) | CoroutineClosure(..) @@ -716,7 +718,8 @@ 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_normalization(); 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 ed587cbc3c285..5fbe7947a8ba3 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}; @@ -300,7 +300,8 @@ 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_normalization() + == args[param.index as usize] }) }) .count(); @@ -330,8 +331,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_normalization()) { if inst == args[param.index as usize] { default_param_seen = true; @@ -368,23 +370,25 @@ impl<'tcx> GenericPredicates<'tcx> { self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> InstantiatedPredicates<'tcx> { + ) -> Unnormalized> { let mut instantiated = InstantiatedPredicates::empty(); self.instantiate_into(tcx, &mut instantiated, args); - instantiated + Unnormalized::new(instantiated) } pub fn instantiate_own( self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator { + ) -> impl Iterator, Span)>> + DoubleEndedIterator + ExactSizeIterator + { EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) } pub fn instantiate_own_identity( self, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator { + ) -> impl Iterator, Span)>> + DoubleEndedIterator + ExactSizeIterator + { EarlyBinder::bind(self.predicates).iter_identity_copied() } @@ -399,15 +403,20 @@ impl<'tcx> GenericPredicates<'tcx> { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, args); } instantiated.predicates.extend( - self.predicates.iter().map(|(p, _)| EarlyBinder::bind(*p).instantiate(tcx, args)), + self.predicates + .iter() + .map(|(p, _)| EarlyBinder::bind(*p).instantiate(tcx, args).skip_normalization()), ); instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp)); } - pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { + pub fn instantiate_identity( + self, + tcx: TyCtxt<'tcx>, + ) -> Unnormalized> { let mut instantiated = InstantiatedPredicates::empty(); self.instantiate_identity_into(tcx, &mut instantiated); - instantiated + Unnormalized::new(instantiated) } fn instantiate_identity_into( @@ -438,25 +447,27 @@ impl<'tcx> ConstConditions<'tcx> { self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + ) -> Unnormalized, Span)>> { let mut instantiated = vec![]; self.instantiate_into(tcx, &mut instantiated, args); - instantiated + Unnormalized::new(instantiated) } pub fn instantiate_own( self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator - { + ) -> impl Iterator, Span)>> + + DoubleEndedIterator + + ExactSizeIterator { EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) } pub fn instantiate_own_identity( self, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator - { + ) -> impl Iterator, Span)>> + + DoubleEndedIterator + + ExactSizeIterator { EarlyBinder::bind(self.predicates).iter_identity_copied() } @@ -471,14 +482,19 @@ impl<'tcx> ConstConditions<'tcx> { tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args); } instantiated.extend( - self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)), + self.predicates.iter().map(|&(p, s)| { + (EarlyBinder::bind(p).instantiate(tcx, args).skip_normalization(), s) + }), ); } - pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + pub fn instantiate_identity( + self, + tcx: TyCtxt<'tcx>, + ) -> Unnormalized, Span)>> { let mut instantiated = vec![]; self.instantiate_identity_into(tcx, &mut instantiated); - instantiated + Unnormalized::new(instantiated) } fn instantiate_identity_into( diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index c935869b504cd..01fc2b6d3303f 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -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_normalization(); 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_normalization() + .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..1bac4db1645ef 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_normalization() + .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..c176c98c260bc 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_normalization(); 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_normalization() } else { - v.instantiate_identity() + v.instantiate_identity().skip_normalization() } } @@ -883,7 +883,7 @@ impl<'tcx> Instance<'tcx> { if let Some(args) = self.args_for_mir_body() { tcx.instantiate_and_normalize_erasing_regions(args, typing_env, v) } else { - tcx.normalize_erasing_regions(typing_env, v.instantiate_identity()) + tcx.normalize_erasing_regions(typing_env, v.instantiate_identity().skip_normalization()) } } @@ -906,7 +906,10 @@ impl<'tcx> Instance<'tcx> { // instantiation of the `FnDef`, so the MIR body // is already instantiated. Any generic parameters it // contains are generic parameters from the caller. - tcx.try_normalize_erasing_regions(typing_env, v.instantiate_identity()) + tcx.try_normalize_erasing_regions( + typing_env, + v.instantiate_identity().skip_normalization(), + ) } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index dbf7d643a42ce..c34f8909ca499 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -877,8 +877,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_normalization(); + let other_ty = other.ty.instantiate_identity().skip_normalization(); (self_ty, other_ty).error_reported()?; // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { @@ -1364,7 +1364,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_normalization() } /// Computes the `Ident` of this variant by looking up the `Span` @@ -1787,7 +1787,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_normalization().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..ae67ecb1c0720 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -133,7 +133,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable>, { - let instantiated = value.instantiate(self, param_args); + let instantiated = value.instantiate(self, param_args).skip_normalization(); self.normalize_erasing_regions(typing_env, instantiated) } @@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable>, { - let instantiated = value.instantiate(self, param_args); + let instantiated = value.instantiate(self, param_args).skip_normalization(); self.try_normalize_erasing_regions(typing_env, instantiated) } } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 3baeb7141de50..948f7ee46a473 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_normalization(); // 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..e04e2dfcd8539 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -48,15 +48,19 @@ 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate(tcx, args).skip_normalization() + }), ) } 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate_identity().skip_normalization() + }), ) }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 1262974325a1f..cb372ac1d3d49 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,11 @@ 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_normalization(); if self.tcx().codegen_fn_attrs(def_id).safe_target_features { write!(self, "#[target_features] ")?; sig = sig.map_bound(|mut sig| { @@ -845,8 +849,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_normalization() + .kind() { if d == def_id { // If the type alias directly starts with the `impl` of the @@ -1085,7 +1093,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_normalization) + { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 08bfe15137a24..5a02791ec4e86 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -156,7 +156,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_normalization() } }) }) @@ -872,7 +874,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_normalization().into() } } }); @@ -1756,7 +1758,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_normalization()) } // We don't know the metadata of `self`, but it must be equal to the @@ -1947,9 +1949,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_normalization().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 3e69eda11ca63..f4295ced75cd7 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -223,7 +223,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_normalization(); 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..452dba7063816 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -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_normalization().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_normalization(); if self.is_mutable_static(def_id) { Ty::new_mut_ptr(self, static_ty) } else if self.is_foreign_item(def_id) { @@ -738,8 +742,10 @@ impl<'tcx> TyCtxt<'tcx> { /// Get the type of the pointer to the static that we use in MIR. pub fn static_ptr_ty(self, def_id: DefId, typing_env: ty::TypingEnv<'tcx>) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. - let static_ty = - self.normalize_erasing_regions(typing_env, self.type_of(def_id).instantiate_identity()); + let static_ty = self.normalize_erasing_regions( + typing_env, + self.type_of(def_id).instantiate_identity().skip_normalization(), + ); // Make sure that accesses to unsafe statics end up using raw pointers. // For thread-locals, this needs to be kept in sync with `Rvalue::ty`. @@ -924,7 +930,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_normalization(); depth += 1; } @@ -987,7 +993,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_normalization(); let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, args), expanded_ty); expanded_ty @@ -1067,7 +1073,11 @@ 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_normalization() + .fold_with(self) }); self.depth -= 1; ty diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 01c1e2e79b501..563f3f77c87f0 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_normalization().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_normalization(), 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_normalization(), ); (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_normalization(); match closure_ty.kind() { ty::Closure(_, args) => { let args = args.as_closure(); @@ -855,8 +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() + .fn_sig(self.def_id).instantiate_identity().skip_normalization() .skip_binder() .output() .is_inhabited_from( diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index f22ff92c01782..a1de05e508de6 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_normalization() } 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..e7ddad4ffda4b 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_normalization(), + ) { 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_normalization(), + ) { // Look for local consts. let item_name = cx.tcx.item_name(item.owner_id); diff --git a/compiler/rustc_mir_transform/src/check_call_recursion.rs b/compiler/rustc_mir_transform/src/check_call_recursion.rs index cac6308617acf..a0aefcc85c18b 100644 --- a/compiler/rustc_mir_transform/src/check_call_recursion.rs +++ b/compiler/rustc_mir_transform/src/check_call_recursion.rs @@ -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_normalization().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_normalization() && sig.inputs().skip_binder().len() == 1 { // It was. Now figure out for what type `Drop` is implemented and then diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index aa945266413d0..3226dddaa7067 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -47,8 +47,10 @@ 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_normalization().kind() { + ty::FnDef(..) => { + tcx.fn_sig(def_id).instantiate_identity().skip_normalization().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..1373baad563fd 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_normalization().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 53aa5f450dbb3..193b33796085d 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_normalization(); 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..002e99fe7f74f 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_normalization(); 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 68c47ec4c1922..eedc49c971dbc 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_normalization().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_normalization().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 1fe745a5d5197..b441e40743037 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -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_normalization(); let sig = tcx.instantiate_bound_regions_with_erased(sig); (sig.output(), drop_fn_def_id, trait_args) }; diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 0216e0d4cfbc5..7f20ebaa5d15f 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -75,16 +75,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { for bound in bounds { if let Some(bound_ty) = self.is_pointer_trait(bound) { // Get the argument types as they appear in the function signature. - let arg_defs = - self.tcx.fn_sig(def_id).instantiate_identity().skip_binder().inputs(); + let arg_defs = self + .tcx + .fn_sig(def_id) + .instantiate_identity() + .skip_normalization() + .skip_binder() + .inputs(); for (arg_num, arg_def) in arg_defs.iter().enumerate() { // For all types reachable from the argument type in the fn sig for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) { // 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_normalization(); if let Some((fn_id, fn_args)) = FunctionItemRefChecker::is_fn_ref(instantiated_ty) { @@ -151,7 +157,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_normalization(); 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/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index 71e4d5581ddc2..aedc72a05eefa 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -37,7 +37,7 @@ use crate::pass_manager::MirPass; pub(crate) struct ImpossiblePredicates; fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); + let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx).skip_normalization(); tracing::trace!(?predicates); let predicates = predicates.predicates.into_iter().filter(|p| { !p.has_type_flags( diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index afcea3236dbda..617554fd45d01 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -572,7 +572,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_normalization(); // 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/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 0ddb9157c7db1..f1cf6d97ca4b7 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_normalization() == ty && tcx.visibility(def_id).is_accessible_from(body_def_id, tcx) }) .collect::>(); diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index bebd8fab74565..ce54547afe579 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -13,7 +13,12 @@ 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_normalization() + .is_coroutine() + { return; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4fd0629befecf..2273ef75340a8 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -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_normalization(); 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_normalization(); 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_normalization(); 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_normalization() } else { - sig.instantiate_identity() + sig.instantiate_identity().skip_normalization() }; 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_normalization(); ( Operand::Constant(Box::new(ConstOperand { span, @@ -1036,6 +1037,7 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let sig = tcx .fn_sig(ctor_id) .instantiate_identity() + .skip_normalization() .no_bound_vars() .expect("LBR in ADT constructor signature"); let sig = tcx.normalize_erasing_regions(typing_env, sig); @@ -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_normalization().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,8 @@ 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_normalization(); 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..53c602f14a544 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,8 @@ 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_normalization(); // Minimal shim passes except MentionedItems, // it causes error "mentioned_items for DefId(...async_drop_in_place...) have already been set @@ -212,7 +213,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_normalization(); 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..483997bfb70c6 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -24,7 +24,12 @@ 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_normalization() + .is_coroutine() + { return; } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 697de3702b6ac..851104aecc0ac 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -685,9 +685,12 @@ 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() - } + &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => self + .tcx + .type_of(def_id) + .instantiate(self.tcx, args) + .skip_normalization() + .kind(), kind => kind, }; @@ -789,7 +792,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_normalization() } else { let Some(&f_ty) = args.as_coroutine().prefix_tys().get(f.index()) else { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5c21ff1464c3d..11e671f99c54c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1533,8 +1533,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_normalization(); assert!(!ty.has_non_region_param()); visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); } @@ -1598,25 +1601,36 @@ impl<'v> RootCollector<'_, 'v> { match self.tcx.def_kind(def_id) { 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() { - ty::Coroutine(cor_id, _args) => { - let tcx = self.tcx; - let parent_id = tcx.parent(cor_id); - tcx.def_kind(parent_id) == DefKind::Fn - && tcx.asyncness(parent_id).is_async() - && tcx.visibility(parent_id).is_public() - } - ty::Closure(..) | ty::CoroutineClosure(..) => false, - _ => unreachable!(), - }; + let is_pub_fn_coroutine = match *self + .tcx + .type_of(def_id) + .instantiate_identity() + .skip_normalization() + .kind() + { + ty::Coroutine(cor_id, _args) => { + let tcx = self.tcx; + let parent_id = tcx.parent(cor_id); + tcx.def_kind(parent_id) == DefKind::Fn + && tcx.asyncness(parent_id).is_async() + && tcx.visibility(parent_id).is_public() + } + ty::Closure(..) | ty::CoroutineClosure(..) => false, + _ => unreachable!(), + }; if (self.strategy == MonoItemCollectionStrategy::Eager || is_pub_fn_coroutine) && !self .tcx .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_normalization() + .kind() + { ty::Closure(def_id, args) | ty::Coroutine(def_id, args) | ty::CoroutineClosure(def_id, args) => { @@ -1750,7 +1764,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_normalization(); // Unlike 'lazy' monomorphization that begins by collecting items transitively // called by `main` or other global items, when eagerly monomorphizing impl 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 a4f331d3fe718..1dd9c9549a1dc 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}; @@ -766,6 +766,7 @@ where .cx() .item_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_normalization) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -781,6 +782,7 @@ where .cx() .item_non_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_normalization) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -1061,6 +1063,7 @@ where .cx() .item_self_bounds(alias_ty.kind.def_id()) .iter_instantiated(self.cx(), alias_ty.args) + .map(Unnormalized::skip_normalization) { 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..331522a2f2a09 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_normalization() .map_bound(|bound| bound.types.to_vec())), ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), @@ -94,15 +95,20 @@ 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_normalization) + .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_normalization(), + ])) } } } @@ -178,7 +184,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_normalization()])) } else { Ok(ty::Binder::dummy(vec![])) } @@ -264,6 +270,7 @@ where .cx() .coroutine_hidden_types(def_id) .instantiate(ecx.cx(), args) + .skip_normalization() .map_bound(|bound| bound.types.to_vec())), } } @@ -281,6 +288,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( { Ok(( sig.instantiate(cx, args) + .skip_normalization() .map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())), def_id.into(), args, @@ -759,6 +768,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_normalization) .map(|field_ty| ty::TraitRef::new(cx, destruct_def_id, [field_ty])) .collect(); match adt_def.destructor(cx) { @@ -884,6 +894,7 @@ where cx, cx.explicit_super_predicates_of(trait_ref.def_id) .iter_instantiated(cx, trait_ref.args) + .map(Unnormalized::skip_normalization) .map(|(pred, _)| pred), )); @@ -896,8 +907,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_normalization), + ); } 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..6ccba56011d37 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_normalization) .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_normalization) .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_normalization(); 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_normalization) .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_normalization) .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_normalization) .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_normalization) .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_normalization) .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..4bc7c832761c5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -217,9 +217,11 @@ where ty::ConstKind::Error(_) => { 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) - } + ty::ConstKind::Unevaluated(uv) => self + .cx() + .type_of(uv.def.into()) + .instantiate(self.cx(), uv.args) + .skip_normalization(), 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..71a4ea9b5697e 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,20 @@ where GoalSource::Misc, cx.predicates_of(free_alias.def_id) .iter_instantiated(cx, free_alias.args) + .map(Unnormalized::skip_normalization) .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_normalization() + .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_normalization() + .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..0d7a6882f5515 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_normalization(), )?; // Equate IAT with the RHS of the project goal @@ -48,13 +48,17 @@ where GoalSource::Misc, cx.predicates_of(inherent.def_id) .iter_instantiated(cx, inherent_args) + .map(Unnormalized::skip_normalization) .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_normalization().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_normalization() + .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..8333481062e56 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_normalization) .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_normalization(); 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_normalization) .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_normalization) .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_normalization(), + ); 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_normalization() } 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_normalization()], + ), }, 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_normalization(); // 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_normalization) .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 a5f857a1dd85b..d6cf58d0546a5 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_normalization(); let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() { ty::ReErased => self.next_region_var(), _ => re, @@ -115,7 +116,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_normalization(); // FIXME: Actually use a proper binder here instead of relying on `ReErased`. // // This is also probably unsound or sth :shrug: @@ -128,7 +130,10 @@ 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_normalization(); 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 44a570fc4fa79..de7f2f92ea19e 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_normalization(); 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_normalization) .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_normalization) .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_normalization) .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_normalization(); + let b_tail_ty = tail_field_ty.instantiate(cx, b_args).skip_normalization(); // 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..9a8f1dc3dd2d1 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_normalization(); 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_normalization(); 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 6aeb0ae57e752..e2438a28ae1f7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1699,7 +1699,7 @@ 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_normalization(), ); let mut cause = ObligationCause::misc(span, def_id); diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index 7f80de9da41f4..069788e061149 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -203,7 +203,7 @@ impl<'tcx, 'a> ExportableItemsChecker<'tcx, 'a> { return; } - let sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); + let sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_normalization().skip_binder(); if !matches!(sig.abi, ExternAbi::C { .. }) { self.tcx.dcx().emit_err(UnexportableItem::FnAbi(span)); return; @@ -280,7 +280,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_normalization(); field_ty.visit_with(self)?; } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d5ef9ee9335c5..c881daf287603 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_normalization() && find_attr!(self.tcx, trait_ref.def_id, RustcTrivialFieldReads) { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() @@ -448,7 +449,8 @@ 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_normalization(); match *self_ty.kind() { ty::Adt(def, _) => self.check_def_id(def.did()), ty::Foreign(did) => self.check_def_id(did), @@ -507,7 +509,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_normalization().kind() && let Some(adt_def_id) = adt.did().as_local() && !self.live_symbols.contains(&adt_def_id) { @@ -927,7 +930,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_normalization(); if field_type.is_phantom_data() { return ShouldWarnAboutField::No; } @@ -1076,8 +1079,11 @@ impl<'tcx> DeadVisitor<'tcx> { tcx.def_kind(dead_item.def_id) && 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() + && let ty::Adt(maybe_enum, _) = tcx + .type_of(impl_did) + .instantiate_identity() + .skip_normalization() + .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 1a9054a51ca39..2e68effd97685 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -64,7 +64,7 @@ pub fn ensure_wf<'tcx>( fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attrs: &[RustcLayoutType]) { 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_normalization(); let span = tcx.def_span(item_def_id.to_def_id()); if !ensure_wf(tcx, typing_env, ty, item_def_id, span) { return; diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 2ec434de61c1f..a54671c6f5d97 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -151,7 +151,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_normalization()) } // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 2147a160d3d6e..2012f08ee6340 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -197,7 +197,12 @@ 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_normalization() + .visit_with(self) + ); } // Inherent static methods don't have self type in args. // Something like `fn() {my_method}` type of the method @@ -206,7 +211,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_normalization() + .visit_with(self) + ); } } ty::Alias( @@ -373,9 +383,11 @@ 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_normalization()); 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_normalization(), + ); } find.min } @@ -832,10 +844,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_normalization(), + ); } if let Some(default) = param.default_value(self.ev.tcx) { - self.visit(default.instantiate_identity()); + self.visit(default.instantiate_identity().skip_normalization()); } } self @@ -852,12 +866,20 @@ 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_normalization(), + ); 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_normalization(), + ); self } } @@ -1260,7 +1282,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_normalization()) + .is_break() + { return; } } else { @@ -1389,10 +1414,12 @@ 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_normalization(), + ); } if let Some(default) = param.default_value(self.tcx) { - let _ = self.visit(default.instantiate_identity()); + let _ = self.visit(default.instantiate_identity().skip_normalization()); } } self @@ -1418,13 +1445,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_normalization()); 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_normalization(), + ); self } @@ -1782,7 +1812,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_normalization(); 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..e0f46e15e1e1c 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_normalization(); 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_normalization() } /// 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..5f98813e83ee8 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_normalization(); 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_normalization(), 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..656976606f88e 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 @@ -143,7 +143,8 @@ 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_normalization(); let is_zst = self .tcx .layout_of(typing_env.as_query_input(ty)) diff --git a/compiler/rustc_symbol_mangling/src/export.rs b/compiler/rustc_symbol_mangling/src/export.rs index 89ee4743a6f43..98d63a0f9f9fc 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_normalization(); 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_normalization(); 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..2b97f41bd0e85 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -32,7 +32,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_normalization(); debug!(?instance_ty); break; } @@ -434,8 +434,10 @@ 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate_identity().skip_normalization() + }), ) } else { assert!( @@ -445,8 +447,10 @@ 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate(self.tcx, args).skip_normalization() + }), ) }; diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index fa839eb845586..a14dd5fde275e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -341,8 +341,10 @@ 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate_identity().skip_normalization() + }), ) } else { assert!( @@ -352,8 +354,10 @@ 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_normalization(), + impl_trait_ref.map(|impl_trait_ref| { + impl_trait_ref.instantiate(self.tcx, args).skip_normalization() + }), ) }; 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..41857cd0a21b6 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_normalization) .find_map(|(predicate, _)| { predicate .kind() @@ -277,7 +278,10 @@ 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_normalization(); let expected_trait_ref = alias.trait_ref(tcx); @@ -307,7 +311,10 @@ 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_normalization(); self.infcx.can_eq(param_env, impl_assoc_ty, concrete) }); @@ -1272,8 +1279,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_normalization(); + let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2).skip_normalization(); self.cmp_fn_sig( &sig1, Some((*did1, Some(args1))), @@ -1283,12 +1290,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_normalization(); 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_normalization(); 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..448c4287c0f62 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 @@ -616,6 +616,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .tcx .fn_sig(body_def_id.to_def_id()) .instantiate_identity() + .skip_normalization() .skip_binder() .output() && let ty::Adt(adt, _args) = ret.kind() @@ -1202,7 +1203,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_normalization(); 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..40c0127668e9c 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_normalization(); 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..c17b667ae7693 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_normalization(); 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_normalization(); 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..f57011138e2bf 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_normalization(); 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_normalization() && 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..60678849ed07c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -12,7 +12,7 @@ use rustc_middle::bug; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ - self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _, + self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Unnormalized, Upcast as _, }; use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, kw, sym}; use tracing::{debug, instrument}; @@ -440,8 +440,11 @@ 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) + .skip_normalization() { if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) = clause.kind().skip_binder() @@ -584,6 +587,7 @@ 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_normalization() // 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; @@ -594,6 +598,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx .explicit_predicates_of(trait_item_def_id) .instantiate_own(self.tcx, trait_item_args) + .map(Unnormalized::skip_normalization) .map(|(pred, _)| { if pred.is_suggestable(self.tcx, false) { Ok(pred.to_string()) 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..dc35acb51445e 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_normalization(), + ); 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_normalization(), + ); + let found_sig = &(self.normalize_fn_sig)( + self.tcx.fn_sig(*did2).instantiate(self.tcx, args2).skip_normalization(), + ); 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_normalization(), + ); 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..cacf813e743ab 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -48,7 +48,8 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( ); 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 = + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args).skip_normalization(); let impl_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref); @@ -70,6 +71,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( let obligations = tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_args) + .skip_normalization() .into_iter() .map(|(predicate, _)| { Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) @@ -136,7 +138,8 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( // otherwise would be more appropriate. 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); + let predicates = + tcx.predicates_of(body_id.to_def_id()).instantiate_identity(tcx).skip_normalization(); for (pred, span) in elaborate(tcx, predicates.into_iter()) { let kind = pred.kind(); if let ty::ClauseKind::Trait(trait_pred) = kind.skip_binder() @@ -443,7 +446,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_normalization() )], ) } else if non_blanket_impl_count < 20 { @@ -457,7 +463,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_normalization() ) }) .collect::>(), 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 5e7a59bd7ae8e..485d885538f6c 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 @@ -2024,7 +2024,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_normalization(), def_id)) }) .filter(|(trait_ref, _)| { let self_ty = trait_ref.self_ty(); @@ -2080,13 +2080,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let impl_trait_ref = ocx.normalize( &ObligationCause::dummy(), param_env, - ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args), + ty::EarlyBinder::bind(single.trait_ref) + .instantiate(self.tcx, impl_args) + .skip_normalization(), ); ocx.register_obligations( self.tcx .predicates_of(single.impl_def_id) .instantiate(self.tcx, impl_args) + .skip_normalization() .into_iter() .map(|(clause, _)| { Obligation::new( @@ -3701,7 +3704,11 @@ 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_normalization(); 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 69afa4f20b3eb..263368f5c81f5 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,8 @@ 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_normalization(); let mut w = "impl".to_owned(); #[derive(Debug, Default)] @@ -485,7 +486,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_normalization() ) .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..9de7a4b0726d1 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,13 @@ 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_normalization() + .to_string(), + ); } for GenericParamDef { name, kind, index, .. } in generics.own_params.iter() { @@ -117,7 +123,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_normalization() + .to_string(), )); } } @@ -160,8 +170,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_normalization() + )); } if aty.is_integral() { self_types.push("[{integral}]".to_string()); @@ -179,7 +191,8 @@ 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_normalization(); 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 e4689e311b64b..9d0c4db64b9b6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1370,8 +1370,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_normalization() + .iter() + .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() && self .tcx @@ -1387,8 +1391,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() @@ -2509,7 +2512,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // the uninstantiated predicate list of the called function. And check // 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 predicates = + self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).skip_normalization() && let Some(pred) = predicates.predicates.get(idx) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() && self.tcx.is_fn_trait(trait_pred.def_id()) @@ -3305,7 +3309,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_normalization(), )) }) .collect::>(); @@ -4491,8 +4497,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut type_diffs = vec![]; if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) - && let where_clauses = - self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) + && let where_clauses = self + .tcx + .predicates_of(def_id) + .instantiate(self.tcx, node_args) + .skip_normalization() && let Some(where_pred) = where_clauses.predicates.get(idx) { if let Some(where_pred) = where_pred.as_trait_clause() diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index bc7bdd372baa6..b4e368d7342a4 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_normalization() .error_reported()?; } 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..b00b32664ddad 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -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_normalization() } ty::ConstKind::Param(param_ct) => { param_ct.find_const_ty_from_env(obligation.param_env) @@ -584,8 +584,12 @@ fn derive_cause<'tcx>( source: CandidateSource::Impl(impl_def_id), result: _, } => { - if let Some((_, span)) = - tcx.predicates_of(impl_def_id).instantiate_identity(tcx).iter().nth(idx) + if let Some((_, span)) = tcx + .predicates_of(impl_def_id) + .instantiate_identity(tcx) + .skip_normalization() + .iter() + .nth(idx) { cause = cause.derived_cause(parent_trait_pred, |derived| { ObligationCauseCode::ImplDerived(Box::new(traits::ImplDerivedCause { @@ -623,18 +627,23 @@ fn derive_host_cause<'tcx>( if let Some((_, span)) = tcx .predicates_of(impl_def_id) .instantiate_identity(tcx) + .skip_normalization() .into_iter() - .chain(tcx.const_conditions(impl_def_id).instantiate_identity(tcx).into_iter().map( - |(trait_ref, span)| { - ( - trait_ref.to_host_effect_clause( - tcx, - parent_host_pred.skip_binder().constness, - ), - span, - ) - }, - )) + .chain( + tcx.const_conditions(impl_def_id) + .instantiate_identity(tcx) + .skip_normalization() + .into_iter() + .map(|(trait_ref, span)| { + ( + trait_ref.to_host_effect_clause( + tcx, + parent_host_pred.skip_binder().constness, + ), + span, + ) + }), + ) .nth(idx) { cause = diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a5d33c7f61a59..27860f85e44ff 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -209,11 +209,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_normalization(), + trait_ref: is_of_trait.then(|| { + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_args).skip_normalization() + }), predicates: tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_args) + .skip_normalization() .iter() .map(|(c, _)| c.as_predicate()) .collect(), @@ -535,12 +538,18 @@ 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_normalization(); + + util::elaborate( + tcx, + tcx.predicates_of(impl2_def_id) + .instantiate(tcx, impl2_header.impl_args) + .skip_normalization(), + ) + .elaborate_sized() + .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env)) } fn plug_infer_with_placeholders<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 1ca0aa3bab199..3dcd24be358fc 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_normalization) + }) .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_normalization) .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_normalization) .filter_map(|(pred, span)| { if let ty::ClauseKind::HostEffect(_) = pred.kind().skip_binder() { Some(span) @@ -292,7 +298,7 @@ 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 = predicates.instantiate_identity(tcx).skip_normalization().predicates; 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 +347,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_normalization(), + ); if contains_illegal_self_type_reference( tcx, trait_def_id, @@ -403,7 +411,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_normalization(); // The method's first parameter must be named `self` if !method.is_method() { @@ -569,7 +577,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_normalization(); debug!( "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", receiver_ty, self_ty, method_def_id, result @@ -668,7 +676,11 @@ 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 = tcx + .predicates_of(method.def_id) + .instantiate_identity(tcx) + .skip_normalization() + .predicates; // 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 45e0b5d74af7d..22dcc594966dc 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, TypingMode}; +use rustc_middle::ty::{self, Ty, TypingMode, 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_normalization) .map(|(trait_ref, _)| { trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness) }), @@ -239,7 +240,9 @@ fn evaluate_host_effect_from_conditionally_const_item_bounds<'tcx>( obligation.param_env, obligation.cause.clone(), obligation.recursion_depth, - tcx.const_conditions(alias_ty.kind.def_id()).instantiate(tcx, alias_ty.args), + tcx.const_conditions(alias_ty.kind.def_id()) + .instantiate(tcx, alias_ty.args) + .skip_normalization(), nested, ); nested.extend(const_conditions.into_iter().map(|(trait_ref, _)| { @@ -272,7 +275,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_normalization) + { let bound_clause = clause.kind(); let ty::ClauseKind::HostEffect(data) = bound_clause.skip_binder() else { continue; @@ -411,6 +418,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_normalization() .map_bound(|bound| bound.types.to_vec())), }?; @@ -561,6 +569,7 @@ fn evaluate_host_effect_for_fn_goal<'tcx>( hir::Constness::Const => Ok(tcx .const_conditions(def) .instantiate(tcx, args) + .skip_normalization() .into_iter() .map(|(c, span)| { let code = ObligationCauseCode::WhereClause(def, span); @@ -597,6 +606,7 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>( nested.extend( tcx.const_conditions(impl_.impl_def_id) .instantiate(tcx, impl_.args) + .skip_normalization() .into_iter() .map(|(trait_ref, span)| { Obligation::new( @@ -641,6 +651,7 @@ fn evaluate_host_effect_from_trait_alias<'tcx>( Ok(tcx .const_conditions(def_id) .instantiate(tcx, obligation.predicate.trait_ref.args) + .skip_normalization() .into_iter() .map(|(trait_ref, span)| { Obligation::new( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index a575630a05035..58c141ab2613d 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_normalization(), // 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/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 94ce7631b3c88..94bd0f56184c4 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -625,7 +625,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_normalization(), + ); if let Err(e) = ct.error_reported() { return Err(EvaluateConstErr::EvaluationFailure(e)); } else if ct.has_non_region_infer() || ct.has_non_region_param() { @@ -714,7 +716,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_normalization(), )), Ok(Err(_)) => { let e = tcx.dcx().delayed_bug( @@ -819,7 +821,8 @@ fn instantiate_and_check_impossible_predicates<'tcx>( ) -> 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 = + tcx.predicates_of(key.0).instantiate(tcx, key.1).skip_normalization().predicates; // Specifically check trait fulfillment to avoid an error when trying to resolve // associated items. @@ -895,7 +898,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_normalization(); let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id }; let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { @@ -904,7 +908,9 @@ 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_normalization(), ) }) }); diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 65c4b40d43964..552a322ea5b89 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}; @@ -315,8 +315,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(Unnormalized::skip_normalization) + .map(|(mut predicate, span)| { if free.has_escaping_bound_vars() { (predicate, ..) = BoundVarReplacer::replace_bound_vars( infcx, @@ -327,17 +331,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_normalization() + .fold_with(self) + .into() } else { infcx .tcx .const_of_item(free.def_id) .instantiate(infcx.tcx, free.args) + .skip_normalization() .fold_with(self) .into() }; @@ -413,7 +423,8 @@ 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_normalization(); 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..44082550f0a63 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -13,7 +13,8 @@ use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{ - self, FieldInfo, Term, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Upcast, + self, FieldInfo, Term, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Unnormalized, + Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::sym; @@ -513,7 +514,8 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( ); // Register the obligations arising from the impl and from the associated type itself. - let predicates = tcx.predicates_of(alias_term.def_id).instantiate(tcx, args); + let predicates = + tcx.predicates_of(alias_term.def_id).instantiate(tcx, args).skip_normalization(); for (predicate, span) in predicates { let predicate = normalize_with_depth_to( selcx, @@ -544,9 +546,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_normalization().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_normalization().into() }; let mut term = selcx.infcx.resolve_vars_if_possible(term); @@ -572,7 +574,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_normalization(); if !selcx.infcx.next_trait_solver() { impl_ty = normalize_with_depth_to( selcx, @@ -2061,7 +2063,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_normalization(), obligations: nested } }; Ok(Projected::Progress(progress)) } @@ -2080,7 +2082,8 @@ fn assoc_term_own_obligations<'cx, 'tcx>( let tcx = selcx.tcx(); let predicates = tcx .predicates_of(obligation.predicate.def_id) - .instantiate_own(tcx, obligation.predicate.args); + .instantiate_own(tcx, obligation.predicate.args) + .map(Unnormalized::skip_normalization); for (predicate, span) in predicates { let normalized = normalize_with_depth_to( selcx, 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..41132da0715ab 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -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_normalization()), + ); + constraints.outlives.extend( + outlives + .iter() + .map(|t| EarlyBinder::bind(*t).instantiate(tcx, args).skip_normalization()), + ); + constraints.overflows.extend( + overflows + .iter() + .map(|t| EarlyBinder::bind(*t).instantiate(tcx, args).skip_normalization()), + ); } // 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..a189bcc077c3e 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -237,7 +237,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_normalization(); 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..d3eb6b518c654 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 @@ -106,8 +106,11 @@ fn relate_mir_and_user_args<'tcx>( let args = if is_inherent_assoc_const { let impl_def_id = tcx.parent(def_id); 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 impl_self_ty = ocx.normalize( + &cause, + param_env, + tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_normalization(), + ); let user_self_ty = ocx.normalize(&cause, param_env, args[0].expect_ty()); ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?; @@ -117,7 +120,7 @@ fn relate_mir_and_user_args<'tcx>( args }; - let ty = tcx.type_of(def_id).instantiate(tcx, args); + let ty = tcx.type_of(def_id).instantiate(tcx, args).skip_normalization(); let ty = ocx.normalize(&cause, param_env, ty); debug!("relate_type_and_user_type: ty of def-id is {:?}", ty); @@ -128,7 +131,8 @@ fn relate_mir_and_user_args<'tcx>( // Also, normalize the `instantiated_predicates` // because otherwise we wind up with duplicate "type // outlives" error messages. - let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args); + let instantiated_predicates = + tcx.predicates_of(def_id).instantiate(tcx, args).skip_normalization(); debug!(?instantiated_predicates); for (instantiated_predicate, predicate_span) in instantiated_predicates { @@ -170,7 +174,7 @@ fn relate_mir_and_user_args<'tcx>( )); 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 = tcx.type_of(impl_def_id).instantiate(tcx, args).skip_normalization(); let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty); ocx.eq(&cause, param_env, self_ty, impl_self_ty)?; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e948994b8689c..1e19a6b9a27ea 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_normalization) { 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_normalization(), &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_normalization(), &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_normalization(), &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 527353bed5ade..d0b0e44f99248 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; @@ -979,9 +979,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_normalization(), // FIXME(generic_const_exprs): See comment in `fulfill.rs` ty::ConstKind::Expr(_) => return Ok(EvaluatedToOk), ty::ConstKind::Placeholder(_) => { @@ -1667,7 +1669,8 @@ 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_normalization() + { for_each(self, bound, idx, alias_bound_kind)?; idx += 1; } @@ -2182,7 +2185,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_normalization()]) } else { ty::Binder::dummy(vec![]) } @@ -2254,6 +2257,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { .tcx .coroutine_hidden_types(def_id) .instantiate(self.infcx.tcx, args) + .skip_normalization() .map_bound(|witness| witness.types.to_vec()), ty::Closure(_, args) => ty::Binder::dummy(args.as_closure().upvar_tys().to_vec()), @@ -2386,6 +2390,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { .tcx .coroutine_hidden_types(def_id) .instantiate(self.infcx.tcx, args) + .skip_normalization() .map_bound(|witness| AutoImplConstituents { types: witness.types.to_vec(), assumptions: witness.assumptions.to_vec(), @@ -2413,7 +2418,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_normalization()], assumptions: vec![], }) } @@ -2516,7 +2521,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_normalization(); debug!(?impl_trait_header); let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = @@ -2828,7 +2834,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // that order. let predicates = tcx.predicates_of(def_id); assert_eq!(predicates.parent, None); - let predicates = predicates.instantiate_own(tcx, args); + let predicates = + predicates.instantiate_own(tcx, args).map(Unnormalized::skip_normalization); let mut obligations = PredicateObligations::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { let cause = if tcx.is_lang_item(parent_trait_pred.def_id(), LangItem::CoerceUnsized) { @@ -2861,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_normalization) + { 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 fa9d617604e50..ab5e1a0b875f6 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -116,8 +116,11 @@ pub fn translate_args_with_cause<'tcx>( "translate_args({:?}, {:?}, {:?}, {:?})", param_env, source_impl, source_args, target_node ); - let source_trait_ref = - infcx.tcx.impl_trait_ref(source_impl).instantiate(infcx.tcx, source_args); + let source_trait_ref = infcx + .tcx + .impl_trait_ref(source_impl) + .instantiate(infcx.tcx, source_args) + .skip_normalization(); // translate the Self and Param parts of the generic parameters, since those // vary across impls @@ -176,7 +179,11 @@ fn fulfill_implication<'tcx>( let target_trait_ref = ocx.normalize( cause, param_env, - infcx.tcx.impl_trait_ref(target_impl).instantiate(infcx.tcx, target_args), + infcx + .tcx + .impl_trait_ref(target_impl) + .instantiate(infcx.tcx, target_args) + .skip_normalization(), ); // do the impls unify? If not, no specialization. @@ -188,7 +195,11 @@ fn fulfill_implication<'tcx>( let predicates = ocx.normalize( cause, param_env, - infcx.tcx.predicates_of(target_impl).instantiate(infcx.tcx, target_args), + infcx + .tcx + .predicates_of(target_impl) + .instantiate(infcx.tcx, target_args) + .skip_normalization(), ); let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates); ocx.register_obligations(obligations); @@ -279,7 +290,7 @@ pub(super) fn specializes( let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let specializing_impl_trait_ref = - specializing_impl_trait_header.trait_ref.instantiate_identity(); + specializing_impl_trait_header.trait_ref.instantiate_identity().skip_normalization(); let cause = &ObligationCause::dummy(); debug!( "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", @@ -303,7 +314,11 @@ pub(super) fn specializes( let parent_impl_trait_ref = ocx.normalize( cause, param_env, - infcx.tcx.impl_trait_ref(parent_impl_def_id).instantiate(infcx.tcx, parent_args), + infcx + .tcx + .impl_trait_ref(parent_impl_def_id) + .instantiate(infcx.tcx, parent_args) + .skip_normalization(), ); // do the impls unify? If not, no specialization. @@ -318,7 +333,11 @@ pub(super) fn specializes( let predicates = ocx.normalize( cause, param_env, - infcx.tcx.predicates_of(parent_impl_def_id).instantiate(infcx.tcx, parent_args), + infcx + .tcx + .predicates_of(parent_impl_def_id) + .instantiate(infcx.tcx, parent_args) + .skip_normalization(), ); let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates); ocx.register_obligations(obligations); @@ -348,7 +367,11 @@ pub(super) fn specializes( let const_conditions = ocx.normalize( cause, param_env, - infcx.tcx.const_conditions(parent_impl_def_id).instantiate(infcx.tcx, parent_args), + infcx + .tcx + .const_conditions(parent_impl_def_id) + .instantiate(infcx.tcx, parent_args) + .skip_normalization(), ); ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, _)| { Obligation::new( diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c3f46aa51c737..ef637f9c33b5c 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_normalization) .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..a042e3b532fc4 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_normalization) .filter_map(move |(pred, _)| { pred.instantiate_supertrait(tcx, ty::Binder::dummy(inner_most_trait_ref)) .as_trait_clause() @@ -276,7 +278,10 @@ fn vtable_entries<'tcx>( // do not hold for this particular set of type parameters. // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args); + let predicates = tcx + .predicates_of(def_id) + .instantiate_own(tcx, args) + .map(Unnormalized::skip_normalization); if impossible_predicates( tcx, predicates.map(|(predicate, _)| predicate).collect(), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 377505ee5f0d2..f0419b1f17ff8 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -583,7 +583,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { origins.extend(iter::repeat(parent).take(head.predicates.len())); } - let predicates = predicates.instantiate(self.tcx(), args); + let predicates = predicates.instantiate(self.tcx(), args).skip_normalization(); trace!("{:#?}", predicates); debug_assert_eq!(predicates.predicates.len(), origins.len()); @@ -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_normalization(); 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_normalization(); 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_normalization(); let predicate = ty::PredicateKind::Clause( ty::ClauseKind::ConstArgHasType(field_val, field_ty), ); diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index d33ade7a9e15d..52cefec46bdcc 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_normalization(); 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..7bca27737e778 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -2,7 +2,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::traits::PredicateObligations; use rustc_middle::query::Providers; -use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; +use rustc_middle::ty::{ParamEnvAnd, TyCtxt, Unnormalized}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::normalize::NormalizationResult; @@ -75,21 +75,26 @@ 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(Unnormalized::skip_normalization) + .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_normalization().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_normalization() + .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..96a7ece90bb78 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -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_normalization(), + ); // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. if let ty::InstanceKind::VTableShim(..) = instance.def { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 09e7eb93504c3..f419b0b70dda9 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_normalization(); 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_normalization(); 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_normalization()] }; let mut impl_spans = impl_spans(tcx, def_id); @@ -113,11 +113,15 @@ 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_normalization() + .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_normalization) .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 cf881961b3ce3..9d0825e6be28d 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -190,6 +190,7 @@ fn resolve_associated_item<'tcx>( let predicates = tcx .predicates_of(impl_data.impl_def_id) .instantiate(tcx, impl_data.args) + .skip_normalization() .predicates; let sized_def_id = tcx.lang_items().sized_trait(); // If we find a `Self: Sized` bound on the item, then we know diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 136df923ee47a..95cd48b9fa3aa 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -521,7 +521,10 @@ 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_normalization(), + ); cx.spanned_layout_of(uninit_ty, local.source_info.span) }) .try_collect::>()?; @@ -679,7 +682,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_normalization() + .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..0a788c3e832a2 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -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_normalization(), ); } } @@ -335,7 +337,9 @@ 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_normalization(), + ); } } _ => vec.push(subty), @@ -368,7 +372,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_normalization(); debug!( "drop_tys_helper: Instantiate into {:?} with {:?} getting {:?}", field, args, r @@ -425,7 +429,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_normalization(), ty::TypingEnv::non_body_analysis(tcx, def_id), adt_has_dtor, false, @@ -445,7 +449,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_normalization(), ty::TypingEnv::non_body_analysis(tcx, def_id), adt_has_dtor, false, @@ -464,7 +468,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_normalization(), // 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 b5fa54d42ffb5..3b95497f16f8a 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_normalization) { 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, alias_ty.args).visit_with(self); + self.tcx + .type_of(def_id) + .instantiate(self.tcx, alias_ty.args) + .skip_normalization() + .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_normalization(); // 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_normalization() .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_normalization(); 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..9b06c6afacfc7 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_normalization(), + ); } 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_normalization(), &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..ac235b05adc14 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,13 +31,13 @@ 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_normalization(); // 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) { + for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx).skip_normalization() { try_visit!(visitor.visit(span, pred)); } } @@ -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_normalization())); } - for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { + for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx).skip_normalization() { try_visit!(visitor.visit(span, pred)); } } 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_normalization) { 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_normalization(); try_visit!(visitor.visit(span, ty)); let ty::Adt(def, args) = ty.kind() else { span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind()) @@ -77,7 +77,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( let ty = field.ty(tcx, args); try_visit!(visitor.visit(span, ty)); } - for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { + for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx).skip_normalization() { try_visit!(visitor.visit(span, pred)); } } @@ -88,20 +88,20 @@ 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_normalization().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())); - for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { + try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity().skip_normalization())); + for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx).skip_normalization() { try_visit!(visitor.visit(span, pred)); } } DefKind::TraitAlias | DefKind::Trait => { - for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) { + for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx).skip_normalization() { try_visit!(visitor.visit(span, pred)); } } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 77d23060ba9e4..abc9b68122782 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_normalization(); 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_normalization(); let constraint_ty = sizedness_constraint_for_ty(tcx, sizedness, tail_ty)?; @@ -151,7 +151,7 @@ fn adt_sizedness_constraint<'tcx>( fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // Compute the bounds on Self and the type parameters. let ty::InstantiatedPredicates { mut predicates, .. } = - tcx.predicates_of(def_id).instantiate_identity(tcx); + tcx.predicates_of(def_id).instantiate_identity(tcx).skip_normalization(); // Finally, we have to normalize the bounds in the environment, in // case they contain any associated type projections. This process @@ -170,7 +170,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_normalization(); // We accounted for the binder of the fn sig, so skip the binder. sig.skip_binder().visit_with(&mut ImplTraitInTraitFinder { tcx, @@ -186,9 +186,13 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // 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), - ), + tcx.const_conditions(def_id) + .instantiate_identity(tcx) + .skip_normalization() + .into_iter() + .map(|(trait_ref, _)| { + trait_ref.to_host_effect_clause(tcx, ty::BoundConstness::Maybe) + }), ); } @@ -259,7 +263,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_normalization(); self.predicates.push( ty::Binder::bind_with_vars( @@ -280,6 +285,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_normalization) { bound.visit_with(self); } @@ -327,7 +333,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_normalization().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); } @@ -336,7 +342,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_normalization().walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.remove(i); } @@ -356,7 +362,7 @@ 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_normalization(), &cause, |ty| { ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| { diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 76140e6a762fe..33f86e1a5c32a 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..df45ecb746022 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_normalization) .enumerate() .map(map_to_child_clause), ), Filter::OnlySelf => self.extend_deduped( cx.explicit_super_predicates_of(data.def_id()) .iter_identity() + .map(Unnormalized::skip_normalization) .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_normalization) + .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_normalization) + { 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..a5ed1411e517e 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_normalization(); + let b_ty = cx.type_of(bu.def.into()).instantiate(cx, bu.args).skip_normalization(); 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..14794367f4989 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_normalization() + } 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..367489753771b --- /dev/null +++ b/compiler/rustc_type_ir/src/unnormalized.rs @@ -0,0 +1,18 @@ +/// A wrapper for value that needs normalization. +/// FIXME: This is very WIP. The plan is to replace the `skip_normalization` spread +/// throughout the codebase with proper normalization. This is the first step toward +/// switching to eager normalization with the next solver. +#[derive(Clone, PartialOrd, PartialEq, Debug)] +pub struct Unnormalized { + value: T, +} + +impl Unnormalized { + pub fn new(value: T) -> Unnormalized { + Unnormalized { value } + } + + pub fn skip_normalization(self) -> T { + self.value + } +} diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fc61103d939fb..a0e481ce02683 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_normalization(); 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..43ac012f17cfd 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -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_normalization(); 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_normalization(); // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. @@ -62,6 +62,7 @@ pub(crate) fn synthesize_blanket_impls( let predicates = tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_args) + .skip_normalization() .predicates .into_iter() .chain(Some(impl_trait_ref.upcast(tcx))); @@ -95,11 +96,13 @@ 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_normalization(), + ), ThinVec::new(), )), for_: clean_middle_ty( - ty::Binder::dummy(ty.instantiate_identity()), + ty::Binder::dummy(ty.instantiate_identity().skip_normalization()), cx, None, None, @@ -112,7 +115,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_normalization().self_ty(), + ), cx, None, None, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 1451b6db8095d..32fd36c46dddc 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_normalization(); // 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_normalization(); 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_normalization()), 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_normalization()), 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_normalization()), cx, Some(did), None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9e8fc2e99fa8d..753bda0e79eef 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,8 @@ 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_normalization(); let ct = lower_const_arg_for_rustdoc(cx.tcx, c, ty); Term::Constant(clean_middle_const(ty::Binder::dummy(ct))) } @@ -590,7 +593,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_normalization(), + ), cx, Some(def.def_id), None, @@ -611,7 +616,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_normalization(), + ), cx, Some(def.def_id), None, @@ -620,7 +627,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_normalization() + .to_string(), )) } else { None @@ -1328,7 +1339,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_normalization(), + ), cx, Some(assoc_item.def_id), None, @@ -1363,13 +1376,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_normalization(), 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_normalization() + .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 +1441,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 +1530,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_normalization(), ), cx, Some(assoc_item.def_id), @@ -1529,7 +1552,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_normalization(), ), cx, Some(assoc_item.def_id), @@ -2267,7 +2292,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_normalization(); clean_middle_ty(bound_ty.rebind(ty), cx, None, None) } } @@ -2330,6 +2355,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 +2453,9 @@ 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_normalization(), + ), cx, Some(field.did), None, @@ -2491,7 +2519,8 @@ 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_normalization(); // normalize the type to only show concrete types // note: we do not use try_normalize_erasing_regions since we @@ -2516,7 +2545,8 @@ 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_normalization(); // normalize the type to only show concrete types // note: we do not use try_normalize_erasing_regions since we @@ -2860,7 +2890,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_normalization(); let mut ret = Vec::new(); let inner_type = clean_ty_alias_inner_type(ty, cx, &mut ret); @@ -2992,7 +3022,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_normalization()), 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..efe0dafc6dca8 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_normalization(); 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_normalization(); 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..688e4cb358901 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_normalization() + .kind() && adt.is_fundamental() { for ty in generics { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 7eff0b5402b48..e60a58ee067bf 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_normalization(), + )) .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..ebe0c2a3e6904 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2994,8 +2994,9 @@ 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()); + let ty = ty::TypingEnv::post_analysis(tcx, field.did).as_query_input( + tcx.type_of(field.did).instantiate_identity().skip_normalization(), + ); 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..4898deab2fb9e 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_normalization(); 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_normalization(); 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_normalization(); 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..57d23c194cb38 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_normalization(); 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..d2309b415c6d5 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_normalization().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_normalization()) + } 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_normalization()) 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_normalization(); 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_normalization(); 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_normalization().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..c1469bd05c8d0 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_normalization(); 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..e56d81fe66b72 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -159,7 +159,11 @@ 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_normalization(), + call_span, + ident_span, + ) } _ => { return; 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..b1699ccdac513 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_normalization() && 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..43dcc858fc017 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_normalization().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..88bd7aa898b53 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_normalization()) && 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..2f19ade217f8d 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_normalization(); 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_normalization(); 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..8790211a2e2c1 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_normalization() && 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..d9aa7d7c9ec2e 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_normalization()) }) && (!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..d3c42b5f7531f 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_normalization().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_normalization()) } 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_normalization()), 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..6c9555c46144f 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_normalization().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..20cea7db8970e 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -381,7 +381,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_normalization().skip_binder().inputs()[0] .is_ref() { // Trait methods taking `&self` diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index c04163b1c7a07..34ed7477e5805 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_normalization().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..eb69c553beb8d 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_normalization().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..0b79e57e0e5fc 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_normalization().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..8b6a80e0a6ea9 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_normalization().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..7f0ce852f91b5 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_normalization(); 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..940be0a02887d 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_normalization(); 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_normalization(); 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..abf609276a85c 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_normalization(); 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..d3e3cc9920895 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_normalization() && 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/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 79ffe1ea417e4..ce1cb0b42f39e 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_normalization() && 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..76719927c713e 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_normalization().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_normalization().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..14befa66cea76 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_normalization().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..db7e7eaad6cf9 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_normalization() && 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..04b8e991d0733 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_normalization().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_normalization().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..469ff3b5badb9 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_normalization(); 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..c00458a972192 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_normalization(); 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..355152076d686 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 @@ -67,7 +67,7 @@ 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_normalization().output()); let ret_ty = cx .tcx .try_normalize_erasing_regions(cx.typing_env(), ret_ty) 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..fa08de55ee6d0 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_normalization().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_normalization() ) && 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..408851a167fff 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -54,7 +54,7 @@ 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_normalization() && 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) 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..5896678aa75e6 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_normalization() && 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 ae53bd608552c..afd0e3d27f0ed 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_normalization().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_normalization().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..98dd1c9c6dbf3 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_normalization(), ); 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..2219fb977e379 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_normalization().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..22a0880f16168 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_normalization().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..f12e99be8ad69 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_normalization() .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..86c85c424f927 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_normalization() && 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..5b9c94754a87c 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_normalization() } 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..621c0d646c2b6 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_normalization().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..9d2016134846d 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_normalization().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..94b73ede9b0ed 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_normalization() && 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..9e2c122829c0c 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_normalization().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..4bd44e9d63a89 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_normalization())) .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..bc572fee078dd 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_normalization() .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..7c4e351b2f6a7 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_normalization() .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..236ebe05d4ba6 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_normalization(); 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_normalization(); 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_normalization() .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..f9156e1cb4260 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -194,7 +194,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_normalization()) .inputs(); // map IntoIterator generic bounds to their signature @@ -233,7 +233,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_normalization().skip_binder(); sig.inputs().len() == 1 && sig.output().is_bool() }) } @@ -261,7 +261,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_normalization() && sig.skip_binder().output().is_bool() && let [_, search_ty] = *sig.skip_binder().inputs() && let ty::Ref(_, search_ty, Mutability::Not) = *cx @@ -279,7 +279,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &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) { - 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_normalization() } 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..9091d43183068 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_normalization()) { 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..2cc008ec5d305 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_normalization().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..a5341e37ca0ef 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_normalization() .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..ffa490065df12 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_normalization().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..c3264e19506d0 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_normalization() && (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..f7233aa4deb94 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_normalization().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..92f26404f255b 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_normalization().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_normalization(); 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_normalization().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..abf7f018816c2 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_normalization(); 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..810e48f6d4e90 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_normalization() && 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..ac9aae815a47e 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_normalization() .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..dfcc27ea08427 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_normalization().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..257f50ea47c28 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_normalization(); 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..d5aa69dbb1273 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 @@ -178,7 +178,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_normalization().skip_binder(); let predicates = cx.tcx.param_env(fn_id).caller_bounds(); let projection_predicates = predicates .iter() @@ -279,7 +279,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_normalization(); 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 +305,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_normalization() .skip_binder() .inputs()[0]; matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut)) 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..0721684fc5f60 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_normalization(); 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..b1bace72d224e 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_normalization(); 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..39324b029f661 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_normalization() && 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_normalization(); 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_normalization() && 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..7a2fd607762d5 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_normalization() .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..9ca17195737a8 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -380,7 +380,7 @@ 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 = EarlyBinder::bind(typeck.expr_ty(e)).instantiate(tcx, gen_args).skip_normalization(); let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); match self.is_ty_freeze(tcx, typing_env, ty) { IsFreeze::Yes => true, @@ -395,7 +395,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_normalization(); match res { Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did) if let Ok(val) = @@ -588,7 +588,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_normalization(); match init_typeck.qpath_res(init_path, init_expr.hir_id) { Res::Def(DefKind::Ctor(..), _) => return None, Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did) @@ -702,7 +702,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_normalization() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::No => true, IsFreeze::Yes => false, @@ -743,7 +743,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_normalization() && 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 +778,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_normalization() && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) { IsFreeze::Yes => false, IsFreeze::No => { @@ -795,9 +795,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_normalization(), }) - .fold_ty(cx.tcx.type_of(item.owner_id).instantiate_identity()); + .fold_ty(cx.tcx.type_of(item.owner_id).instantiate_identity().skip_normalization()); // `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..7d8e115d9b957 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_normalization().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..645a179af7c21 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_normalization(); ( 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..14eab859e4d74 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_normalization().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..ed0aa3027d238 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_normalization(); 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..4a5cd4e4b1b7c 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_normalization().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_normalization().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..da38d3cf37fd4 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_normalization()) .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_normalization() // 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/returns/let_and_return.rs b/src/tools/clippy/clippy_lints/src/returns/let_and_return.rs index b19935959c4d8..bbf2e1a47d329 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_normalization() .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..3a80e2a1e6ed0 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_normalization(); let ret_ty = return_ty(cx, impl_item.owner_id); // Do not check trait impls 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..996c2727b44eb 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -62,7 +62,7 @@ fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: && 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(), + cx.tcx.type_of(last_field.def_id).instantiate_identity().skip_normalization(), ) && 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 3e6aae475ecce..0edbc101a6207 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 @@ -266,7 +266,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_normalization()); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure { raw_ptr_only: false }; }; 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..dc64a8d73dd53 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_normalization(); 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..ca79d3a6986fc 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_normalization().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..3d887d5b5d4cb 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_normalization(); 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..abe3d71f3a1cc 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_normalization().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_normalization(); 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_normalization() && 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_normalization() && 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_normalization() && 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..22cd4c22e4bce 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_normalization(); 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..8f037ff8f40ff 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_normalization() && 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_normalization() .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..fc25d8913880c 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_normalization() && 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..2746055f67d13 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_normalization().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..0c3fa6f9c238a 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_normalization(), 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_normalization().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_normalization() .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 a8ff9b4cf6fb5..2a10ea1fccf89 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_normalization().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_normalization().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_normalization().input(nth); cx.tcx.instantiate_bound_regions_with_erased(arg) } @@ -2698,7 +2698,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_normalization()), }), Self::Return(id) => { if let Node::Expr(Expr { @@ -2711,7 +2711,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_normalization().output(); Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), ty, @@ -2733,7 +2733,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_normalization()), }), _ => None, }, @@ -3222,7 +3222,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_normalization(); get_path_to_ty(tcx, from, ty, args) }, } @@ -3238,7 +3238,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_normalization()), _ => ty.to_string(), } } @@ -3418,7 +3418,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_normalization(); 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..05c8ed28ca948 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_normalization().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..1d7979ad7e890 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_normalization().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..aac705543b50f 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_normalization(), 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_normalization(), 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)), @@ -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_normalization().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_normalization().ty_adt_def().unwrap(); Some((adt, adt.non_enum_variant())) }, _ => None, 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..e6601ca5e8975 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_normalization()) .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..08f4170c88c8b 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_normalization(), ); 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..2e327d3ad5eb4 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_normalization(); 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 {