fix all errors

This commit is contained in:
Adwin White
2026-04-15 12:17:20 +08:00
parent 3e1e35b5d1
commit 6279106e72
334 changed files with 2352 additions and 1390 deletions
@@ -14,7 +14,7 @@
}; };
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, Unnormalized,
}; };
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -275,7 +275,7 @@ fn nice_error<'infcx>(
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
// test. Check after #85499 lands to see if its fixes have erased this difference. // test. Check after #85499 lands to see if its fixes have erased this difference.
let ty::ParamEnvAnd { param_env, value } = key; let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.normalize(&cause, param_env, value.value); let _ = ocx.normalize(&cause, param_env, Unnormalized::new_wip(value.value));
let diag = try_extract_error_from_fulfill_cx( let diag = try_extract_error_from_fulfill_cx(
&ocx, &ocx,
@@ -322,7 +322,7 @@ fn nice_error<'infcx>(
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let ty::ParamEnvAnd { param_env, value } = key; let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.deeply_normalize(&cause, param_env, value.value); let _ = ocx.deeply_normalize(&cause, param_env, Unnormalized::new_wip(value.value));
let diag = try_extract_error_from_fulfill_cx( let diag = try_extract_error_from_fulfill_cx(
&ocx, &ocx,
@@ -754,19 +754,19 @@ fn suggest_borrow_generic_arg(
} }
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type. // Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| { clauses.instantiate(tcx, new_args).predicates.iter().all(|clause| {
// Normalize before testing to see through type aliases and projections. // Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = tcx.try_normalize_erasing_regions( let normalized = tcx
self.infcx.typing_env(self.infcx.param_env), .try_normalize_erasing_regions(
clause, self.infcx.typing_env(self.infcx.param_env),
) { *clause,
clause = normalized; )
} .unwrap_or_else(|_| clause.skip_norm_wip());
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
tcx, tcx,
ObligationCause::dummy(), ObligationCause::dummy(),
self.infcx.param_env, self.infcx.param_env,
clause, normalized,
)) ))
}) })
}) { }) {
@@ -4222,11 +4222,20 @@ fn annotate_argument_and_return_for_borrow(
if is_closure { if is_closure {
None None
} else { } else {
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity(); let ty = self
.infcx
.tcx
.type_of(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip();
match ty.kind() { match ty.kind() {
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig( ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
self.mir_def_id(), self.mir_def_id(),
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(), self.infcx
.tcx
.fn_sig(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip(),
), ),
_ => None, _ => None,
} }
+10 -4
View File
@@ -1366,9 +1366,12 @@ fn explain_captures(
let parent_self_ty = let parent_self_ty =
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. }) matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
.then_some(parent_did) .then_some(parent_did)
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() { .and_then(|did| {
ty::Adt(def, ..) => Some(def.did()), match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
_ => None, {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
}
}); });
let is_option_or_result = parent_self_ty.is_some_and(|def_id| { 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)) matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
@@ -1445,7 +1448,10 @@ fn explain_captures(
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars( && let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span, fn_call_span,
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0), tcx.fn_sig(method_did)
.instantiate(tcx, method_args)
.skip_norm_wip()
.input(0),
) )
&& self.infcx.can_eq(self.infcx.param_env, ty, self_ty) && self.infcx.can_eq(self.infcx.param_env, ty, self_ty)
{ {
@@ -640,8 +640,9 @@ fn get_closure_bound_clause_span(
// Check whether one of the where-bounds requires the closure to impl `Fn[Mut]` // Check whether one of the where-bounds requires the closure to impl `Fn[Mut]`
// or `AsyncFn[Mut]`. // or `AsyncFn[Mut]`.
for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) { for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) {
let pred = pred.skip_norm_wip();
let dominated_by_fn_trait = self let dominated_by_fn_trait = self
.closure_clause_kind(*pred, def_id, asyncness) .closure_clause_kind(pred, def_id, asyncness)
.is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut)); .is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut));
if dominated_by_fn_trait { if dominated_by_fn_trait {
// Found `<TyOfCapturingClosure as FnMut>` or // Found `<TyOfCapturingClosure as FnMut>` or
@@ -9,6 +9,7 @@
use rustc_middle::mir::{self, ConstraintCategory, Location}; use rustc_middle::mir::{self, ConstraintCategory, Location};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
Unnormalized,
}; };
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic; use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
@@ -282,6 +283,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
.tcx .tcx
.explicit_item_bounds(def_id) .explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.map(Unnormalized::skip_norm_wip)
{ {
bound.visit_with(self)?; bound.visit_with(self)?;
} }
@@ -596,7 +596,7 @@ fn report_fnmut_error(
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; 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() { if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity() output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
}; };
debug!("report_fnmut_error: output_ty={:?}", output_ty); debug!("report_fnmut_error: output_ty={:?}", output_ty);
@@ -933,7 +933,7 @@ fn maybe_suggest_constrain_dyn_trait_impl(
debug!(?fn_did, ?args); debug!(?fn_did, ?args);
// Only suggest this on function calls, not closures // Only suggest this on function calls, not closures
let ty = tcx.type_of(fn_did).instantiate_identity(); let ty = tcx.type_of(fn_did).instantiate_identity().skip_norm_wip();
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind()); debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
if let ty::Closure(_, _) = ty.kind() { if let ty::Closure(_, _) = ty.kind() {
return; return;
@@ -1053,7 +1053,8 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
else { else {
return; return;
}; };
let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind() let ty::Closure(_, args) =
*tcx.type_of(closure_def_id).instantiate_identity().skip_norm_wip().kind()
else { else {
return; return;
}; };
@@ -1151,7 +1152,13 @@ fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
let ocx = ObligationCtxt::new(&self.infcx); let ocx = ObligationCtxt::new(&self.infcx);
ocx.register_obligations(preds.iter().map(|(pred, span)| { ocx.register_obligations(preds.iter().map(|(pred, span)| {
trace!(?pred); trace!(?pred);
Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred) Obligation::misc(
tcx,
span,
self.mir_def_id(),
self.infcx.param_env,
pred.skip_norm_wip(),
)
})); }));
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 { if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {
@@ -6,7 +6,7 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty}; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -418,7 +418,7 @@ fn give_name_if_we_can_match_upvar_args(
// Get the parent fn's signature with liberated late-bound regions, // Get the parent fn's signature with liberated late-bound regions,
// so we have `ReLateParam` instead of `ReBound`. // so we have `ReLateParam` instead of `ReBound`.
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity(); let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip();
let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig); let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig);
let parent_param_ty = *liberated_sig.inputs().get(param_index)?; let parent_param_ty = *liberated_sig.inputs().get(param_index)?;
@@ -1023,10 +1023,10 @@ fn give_name_if_anonymous_region_appears_in_impl_signature(
return None; return None;
}; };
let found = tcx let found = tcx.any_free_region_meets(
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| { &tcx.type_of(region_parent).instantiate_identity().skip_norm_wip(),
r.kind() == ty::ReEarlyParam(region) |r| r.kind() == ty::ReEarlyParam(region),
}); );
Some(RegionName { Some(RegionName {
name: self.synthesize_region_name(), name: self.synthesize_region_name(),
@@ -1051,12 +1051,15 @@ fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait(
return None; return None;
}; };
let predicates = self let predicates: Vec<_> = self
.infcx .infcx
.tcx .tcx
.predicates_of(self.body.source.def_id()) .predicates_of(self.body.source.def_id())
.instantiate_identity(self.infcx.tcx) .instantiate_identity(self.infcx.tcx)
.predicates; .predicates
.into_iter()
.map(Unnormalized::skip_norm_wip)
.collect();
if let Some(upvar_index) = self if let Some(upvar_index) = self
.regioncx .regioncx
@@ -12,7 +12,7 @@
use rustc_middle::ty::{ use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg, self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions,
}; };
use rustc_mir_dataflow::points::DenseLocationMap; use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::Span; use rustc_span::Span;
@@ -569,16 +569,17 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
}; };
// We erase all non-member region of the opaque and need to treat these as existentials. // We erase all non-member region of the opaque and need to treat these as existentials.
let expected_ty = let expected_ty = ty::fold_regions(
ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| { tcx,
match re.kind() { expected.ty.instantiate(tcx, key.args).skip_norm_wip(),
ty::ReErased => infcx.next_nll_region_var( |re, _dbi| match re.kind() {
NllRegionVariableOrigin::Existential { name: None }, ty::ReErased => infcx.next_nll_region_var(
|| crate::RegionCtxt::Existential(None), NllRegionVariableOrigin::Existential { name: None },
), || crate::RegionCtxt::Existential(None),
_ => re, ),
} _ => re,
}); },
);
// We now simply equate the expected with the actual hidden type. // We now simply equate the expected with the actual hidden type.
let locations = Locations::All(hidden_type.span); let locations = Locations::All(hidden_type.span);
@@ -598,8 +599,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
body.source.def_id().expect_local(), body.source.def_id().expect_local(),
); );
// We need to normalize both types in the old solver before equatingt them. // We need to normalize both types in the old solver before equatingt them.
let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty); let actual_ty = ocx.normalize(
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty); &cause,
infcx.param_env,
Unnormalized::new_wip(hidden_type.ty),
);
let expected_ty =
ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty));
ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution) ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
}, },
"equating opaque types", "equating opaque types",
@@ -5,7 +5,7 @@
use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast};
use rustc_span::Span; use rustc_span::Span;
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_trait_selection::solve::NoSolution; use rustc_trait_selection::solve::NoSolution;
@@ -189,7 +189,11 @@ pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation
where where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{ {
self.normalize_with_category(value, location, ConstraintCategory::Boring) self.normalize_with_category(
Unnormalized::new_wip(value),
location,
ConstraintCategory::Boring,
)
} }
pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
@@ -214,6 +218,7 @@ pub(super) fn normalize_with_category<T>(
where where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{ {
let value = value.skip_normalization();
let param_env = self.infcx.param_env; let param_env = self.infcx.param_env;
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
location.to_locations(), location.to_locations(),
@@ -246,11 +251,7 @@ pub(super) fn struct_tail(
CustomTypeOp::new( CustomTypeOp::new(
|ocx| { |ocx| {
let structurally_normalize = |ty| { let structurally_normalize = |ty| {
ocx.structurally_normalize_ty( ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty))
&cause,
param_env,
ty,
)
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR")) .unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
}; };
@@ -295,7 +296,7 @@ pub(super) fn structurally_resolve(
body.source.def_id().expect_local(), body.source.def_id().expect_local(),
), ),
param_env, param_env,
ty, Unnormalized::new_wip(ty),
) )
.map_err(|_| NoSolution) .map_err(|_| NoSolution)
}, },
@@ -364,7 +365,7 @@ pub(super) fn ascribe_user_type_skip_wf(
// obligation for the unnormalized user_ty here. This is // obligation for the unnormalized user_ty here. This is
// where the "incorrectly skips the WF checks we normally do" // where the "incorrectly skips the WF checks we normally do"
// happens // happens
let user_ty = ocx.normalize(&cause, param_env, user_ty); let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty));
ocx.eq(&cause, param_env, user_ty, mir_ty)?; ocx.eq(&cause, param_env, user_ty, mir_ty)?;
Ok(()) Ok(())
}, },
@@ -1759,7 +1759,8 @@ fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Locat
); );
} }
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) { } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity(); let unnormalized_ty =
tcx.type_of(static_def_id).instantiate_identity().skip_norm_wip();
let normalized_ty = self.normalize(unnormalized_ty, locations); let normalized_ty = self.normalize(unnormalized_ty, locations);
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap(); let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
@@ -585,7 +585,7 @@ fn defining_ty(&self) -> DefiningTy<'tcx> {
match tcx.hir_body_owner_kind(self.mir_def) { match tcx.hir_body_owner_kind(self.mir_def) {
BodyOwnerKind::Closure | BodyOwnerKind::Fn => { BodyOwnerKind::Closure | BodyOwnerKind::Fn => {
let defining_ty = tcx.type_of(self.mir_def).instantiate_identity(); let defining_ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip();
debug!("defining_ty (pre-replacement): {:?}", defining_ty); debug!("defining_ty (pre-replacement): {:?}", defining_ty);
@@ -780,7 +780,7 @@ fn compute_inputs_and_output(
} }
DefiningTy::FnDef(def_id, _) => { DefiningTy::FnDef(def_id, _) => {
let sig = tcx.fn_sig(def_id).instantiate_identity(); let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let sig = indices.fold_to_region_vids(tcx, sig); let sig = indices.fold_to_region_vids(tcx, sig);
let inputs_and_output = sig.inputs_and_output(); let inputs_and_output = sig.inputs_and_output();
@@ -804,7 +804,8 @@ fn compute_inputs_and_output(
.infcx .infcx
.tcx .tcx
.type_of(va_list_did) .type_of(va_list_did)
.instantiate(self.infcx.tcx, &[region.into()]); .instantiate(self.infcx.tcx, &[region.into()])
.skip_norm_wip();
// The signature needs to follow the order [input_tys, va_list_ty, output_ty] // The signature needs to follow the order [input_tys, va_list_ty, output_ty]
return inputs_and_output.map_bound(|tys| { return inputs_and_output.map_bound(|tys| {
@@ -822,7 +823,7 @@ fn compute_inputs_and_output(
// For a constant body, there are no inputs, and one // For a constant body, there are no inputs, and one
// "output" (the type of the constant). // "output" (the type of the constant).
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let ty = tcx.type_of(self.mir_def).instantiate_identity(); let ty = tcx.type_of(self.mir_def).instantiate_identity().skip_norm_wip();
let ty = indices.fold_to_region_vids(tcx, ty); let ty = indices.fold_to_region_vids(tcx, ty);
ty::Binder::dummy(tcx.mk_type_list(&[ty])) ty::Binder::dummy(tcx.mk_type_list(&[ty]))
@@ -834,9 +835,9 @@ fn compute_inputs_and_output(
ty::Binder::dummy(tcx.mk_type_list(&[ty])) ty::Binder::dummy(tcx.mk_type_list(&[ty]))
} }
DefiningTy::GlobalAsm(def_id) => { DefiningTy::GlobalAsm(def_id) => ty::Binder::dummy(
ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity().skip_norm_wip()]),
} ),
}; };
// FIXME(#129952): We probably want a more principled approach here. // FIXME(#129952): We probably want a more principled approach here.
@@ -974,7 +975,7 @@ fn for_each_late_bound_region_in_item<'tcx>(
// only deduced that a param in the closure signature is late-bound from a constraint // only deduced that a param in the closure signature is late-bound from a constraint
// that we discover during typeck. // that we discover during typeck.
DefKind::Closure => { DefKind::Closure => {
let ty = tcx.type_of(mir_def_id).instantiate_identity(); let ty = tcx.type_of(mir_def_id).instantiate_identity().skip_norm_wip();
match *ty.kind() { match *ty.kind() {
ty::Closure(_, args) => args.as_closure().sig().bound_vars(), ty::Closure(_, args) => args.as_closure().sig().bound_vars(),
ty::CoroutineClosure(_, args) => { ty::CoroutineClosure(_, args) => {
@@ -19,6 +19,7 @@
use rustc_codegen_ssa::debuginfo::type_names; use rustc_codegen_ssa::debuginfo::type_names;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap; use rustc_hir::def_id::DefIdMap;
use rustc_middle::ty::Unnormalized;
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::DebugInfo; use rustc_session::config::DebugInfo;
use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId}; use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId};
@@ -244,7 +245,10 @@ pub(crate) fn define_function<'tcx>(
type_names::push_generic_args( type_names::push_generic_args(
tcx, tcx,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args), tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(args),
),
&mut name, &mut name,
); );
@@ -1,6 +1,6 @@
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::ty::{AssocTag, GenericArg}; use rustc_middle::ty::{AssocTag, GenericArg, Unnormalized};
use rustc_session::config::EntryFnType; use rustc_session::config::EntryFnType;
use rustc_span::{DUMMY_SP, Ident}; use rustc_span::{DUMMY_SP, Ident};
@@ -50,7 +50,7 @@ fn create_entry_fn(
// listing. // listing.
let main_ret_ty = tcx.normalize_erasing_regions( let main_ret_ty = tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(), ty::TypingEnv::fully_monomorphized(),
main_ret_ty.no_bound_vars().unwrap(), Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()),
); );
let cmain_sig = Signature { let cmain_sig = Signature {
@@ -16,7 +16,7 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::mir::BinOp; use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty, Unnormalized};
use rustc_span::{Span, Symbol, sym}; use rustc_span::{Span, Symbol, sym};
use crate::builder::Builder; use crate::builder::Builder;
@@ -539,7 +539,10 @@ macro_rules! require_simd2 {
match *in_elem.kind() { match *in_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) bx.tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(ty),
)
}); });
require!( require!(
metadata.is_unit(), metadata.is_unit(),
@@ -553,7 +556,10 @@ macro_rules! require_simd2 {
match *out_elem.kind() { match *out_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), ty) bx.tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(ty),
)
}); });
require!( require!(
metadata.is_unit(), metadata.is_unit(),
@@ -16,7 +16,8 @@
HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA,
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, self, AdtDef, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt,
Unnormalized, Visibility,
}; };
use rustc_session::config::{self, DebugInfo, Lto}; use rustc_session::config::{self, DebugInfo, Lto};
use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene}; use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene};
@@ -1234,7 +1235,12 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
} }
}; };
assert!(up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(cx.typing_env(), t))); assert!(
up_var_tys
.iter()
.all(|t| t
== cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(t)))
);
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_coroutine_ty); let layout = cx.layout_of(closure_or_coroutine_ty);
@@ -1418,7 +1424,9 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>(
let template_params: SmallVec<_> = iter::zip(args, names) let template_params: SmallVec<_> = iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); let actual_type = cx
.tcx
.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty));
let actual_type_di_node = type_di_node(cx, actual_type); let actual_type_di_node = type_di_node(cx, actual_type);
Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node)) Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node))
}) })
@@ -7,7 +7,7 @@
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt, Unnormalized};
use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::CodegenCx; use crate::common::CodegenCx;
@@ -50,14 +50,23 @@ pub(super) enum UniqueTypeId<'tcx> {
impl<'tcx> UniqueTypeId<'tcx> { impl<'tcx> UniqueTypeId<'tcx> {
pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self { pub(crate) fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
assert_eq!(t, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), t)); assert_eq!(
t,
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(t)
)
);
UniqueTypeId::Ty(t, private::HiddenZst) UniqueTypeId::Ty(t, private::HiddenZst)
} }
pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self { pub(crate) fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
assert_eq!( assert_eq!(
enum_ty, enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
); );
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst) UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
} }
@@ -69,7 +78,10 @@ pub(crate) fn for_enum_variant_struct_type(
) -> Self { ) -> Self {
assert_eq!( assert_eq!(
enum_ty, enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
); );
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst) UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
} }
@@ -81,7 +93,10 @@ pub(crate) fn for_enum_variant_struct_type_wrapper(
) -> Self { ) -> Self {
assert_eq!( assert_eq!(
enum_ty, enum_ty,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), enum_ty) tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(enum_ty)
)
); );
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst) UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
} }
@@ -93,11 +108,17 @@ pub(crate) fn for_vtable_ty(
) -> Self { ) -> Self {
assert_eq!( assert_eq!(
self_type, self_type,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), self_type) tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(self_type)
)
); );
assert_eq!( assert_eq!(
implemented_trait, implemented_trait,
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), implemented_trait) tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(implemented_trait)
)
); );
UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst) UniqueTypeId::VTableTy(self_type, implemented_trait, private::HiddenZst)
} }
@@ -17,7 +17,7 @@
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::mir; use rustc_middle::mir;
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, GenericArgsRef, Instance, Ty, TypeVisitableExt, Unnormalized};
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::{self, DebugInfo}; use rustc_session::config::{self, DebugInfo};
use rustc_span::{ use rustc_span::{
@@ -458,7 +458,7 @@ fn dbg_scope_fn(
type_names::push_generic_args( type_names::push_generic_args(
tcx, tcx,
tcx.normalize_erasing_regions(self.typing_env(), args), tcx.normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(args)),
&mut name, &mut name,
); );
@@ -595,7 +595,10 @@ fn get_template_parameters<'ll, 'tcx>(
iter::zip(args, names) iter::zip(args, names)
.filter_map(|(kind, name)| { .filter_map(|(kind, name)| {
kind.as_type().map(|ty| { kind.as_type().map(|ty| {
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty); let actual_type = cx.tcx.normalize_erasing_regions(
cx.typing_env(),
Unnormalized::new_wip(ty),
);
let actual_type_metadata = type_di_node(cx, actual_type); let actual_type_metadata = type_di_node(cx, actual_type);
Some(cx.create_template_type_parameter( Some(cx.create_template_type_parameter(
name.as_str(), name.as_str(),
+8 -6
View File
@@ -17,7 +17,9 @@
use rustc_middle::mir::BinOp; use rustc_middle::mir::BinOp;
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
use rustc_middle::ty::offload_meta::OffloadMetadata; use rustc_middle::ty::offload_meta::OffloadMetadata;
use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv}; use rustc_middle::ty::{
self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv, Unnormalized,
};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType; use rustc_session::config::CrateType;
use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC; use rustc_session::lint::builtin::DEPRECATED_LLVM_INTRINSIC;
@@ -814,9 +816,9 @@ fn codegen_llvm_intrinsic_call(
let fn_ty = instance.ty(tcx, self.typing_env()); let fn_ty = instance.ty(tcx, self.typing_env());
let fn_sig = match *fn_ty.kind() { let fn_sig = match *fn_ty.kind() {
ty::FnDef(def_id, args) => { ty::FnDef(def_id, args) => tcx.instantiate_bound_regions_with_erased(
tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)) tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip(),
} ),
_ => unreachable!(), _ => unreachable!(),
}; };
assert!(!fn_sig.c_variadic()); assert!(!fn_sig.c_variadic());
@@ -2933,7 +2935,7 @@ macro_rules! bitwise_red {
match in_elem.kind() { match in_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty))
}); });
require!( require!(
metadata.is_unit(), metadata.is_unit(),
@@ -2947,7 +2949,7 @@ macro_rules! bitwise_red {
match out_elem.kind() { match out_elem.kind() {
ty::RawPtr(p_ty, _) => { ty::RawPtr(p_ty, _) => {
let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(bx.typing_env(), ty) bx.tcx.normalize_erasing_regions(bx.typing_env(), Unnormalized::new_wip(ty))
}); });
require!( require!(
metadata.is_unit(), metadata.is_unit(),
+5 -4
View File
@@ -27,7 +27,7 @@
use rustc_middle::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions}; use rustc_middle::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt}; use rustc_middle::ty::{self, Instance, PatternKind, Ty, TyCtxt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::Session; use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType}; use rustc_session::config::{self, CrateType, EntryFnType};
@@ -519,9 +519,10 @@ fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// late-bound regions, since late-bound // late-bound regions, since late-bound
// regions must appear in the argument // regions must appear in the argument
// listing. // listing.
let main_ret_ty = cx let main_ret_ty = cx.tcx().normalize_erasing_regions(
.tcx() cx.typing_env(),
.normalize_erasing_regions(cx.typing_env(), main_ret_ty.no_bound_vars().unwrap()); Unnormalized::new_wip(main_ret_ty.no_bound_vars().unwrap()),
);
let Some(llfn) = cx.declare_c_main(llfty) else { let Some(llfn) = cx.declare_c_main(llfty) else {
// FIXME: We should be smart and show a better diagnostic here. // FIXME: We should be smart and show a better diagnostic here.
@@ -22,7 +22,9 @@
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::{self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::ty::{
self, ExistentialProjection, GenericArgKind, GenericArgsRef, Ty, TyCtxt, Unnormalized,
};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::debuginfo::wants_c_like_enum_debuginfo; use crate::debuginfo::wants_c_like_enum_debuginfo;
@@ -540,8 +542,10 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
} }
if let Some(trait_ref) = trait_ref { if let Some(trait_ref) = trait_ref {
let trait_ref = let trait_ref = tcx.normalize_erasing_regions(
tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(trait_ref),
);
push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name);
visited.clear(); visited.clear();
push_generic_args_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); push_generic_args_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited);
@@ -654,7 +658,13 @@ fn push_generic_args_internal<'tcx>(
output: &mut String, output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>, visited: &mut FxHashSet<Ty<'tcx>>,
) -> bool { ) -> bool {
assert_eq!(args, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args)); assert_eq!(
args,
tcx.normalize_erasing_regions(
ty::TypingEnv::fully_monomorphized(),
Unnormalized::new_wip(args)
)
);
let mut args = args.non_erasable_generics().peekable(); let mut args = args.non_erasable_generics().peekable();
if args.peek().is_none() { if args.peek().is_none() {
return false; return false;
@@ -399,8 +399,9 @@ fn revalidate_conditional_constness(
ty::BoundConstness::Const ty::BoundConstness::Const
} }
}; };
let const_conditions = let const_conditions = const_conditions.into_iter().map(|(c, s)| {
ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions); (ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, c), s)
});
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| { ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
Obligation::new( Obligation::new(
tcx, tcx,
@@ -66,11 +66,11 @@ fn is_async(&self) -> bool {
pub fn fn_sig(&self) -> PolyFnSig<'tcx> { pub fn fn_sig(&self) -> PolyFnSig<'tcx> {
let did = self.def_id().to_def_id(); let did = self.def_id().to_def_id();
if self.tcx.is_closure_like(did) { if self.tcx.is_closure_like(did) {
let ty = self.tcx.type_of(did).instantiate_identity(); let ty = self.tcx.type_of(did).instantiate_identity().skip_norm_wip();
let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") }; let ty::Closure(_, args) = ty.kind() else { bug!("type_of closure not ty::Closure") };
args.as_closure().sig() args.as_closure().sig()
} else { } else {
self.tcx.fn_sig(did).instantiate_identity() self.tcx.fn_sig(did).instantiate_identity().skip_norm_wip()
} }
} }
} }
@@ -70,7 +70,8 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
body: &'tcx mir::Body<'tcx>, body: &'tcx mir::Body<'tcx>,
) -> InterpResult<'tcx, R> { ) -> InterpResult<'tcx, R> {
let tcx = *ecx.tcx; let tcx = *ecx.tcx;
let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?; let layout =
ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args).skip_norm_wip())?;
let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?; let (intern_kind, ret) = setup_for_eval(ecx, cid, layout)?;
trace!( trace!(
@@ -9,7 +9,7 @@
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::find_attr; use rustc_hir::find_attr;
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, Unnormalized, VariantDef};
use rustc_middle::{bug, mir, span_bug}; use rustc_middle::{bug, mir, span_bug};
use rustc_target::callconv::{ArgAbi, FnAbi}; use rustc_target::callconv::{ArgAbi, FnAbi};
use tracing::field::Empty; use tracing::field::Empty;
@@ -219,7 +219,9 @@ fn layout_compat(
// Even if `ty` is normalized, the search for the unsized tail will project // Even if `ty` is normalized, the search for the unsized tail will project
// to fields, which can yield non-normalized types. So we need to provide a // to fields, which can yield non-normalized types. So we need to provide a
// normalization function. // normalization function.
let normalize = |ty| self.tcx.normalize_erasing_regions(self.typing_env, ty); let normalize = |ty| {
self.tcx.normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(ty))
};
ty.ptr_metadata_ty(*self.tcx, normalize) ty.ptr_metadata_ty(*self.tcx, normalize)
}; };
return interp_ok(meta_ty(caller) == meta_ty(callee)); return interp_ok(meta_ty(caller) == meta_ty(callee));
@@ -37,7 +37,8 @@ fn alloc_caller_location<'tcx>(
let loc_ty = ecx let loc_ty = ecx
.tcx .tcx
.type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span)) .type_of(ecx.tcx.require_lang_item(LangItem::PanicLocation, ecx.tcx.span))
.instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()])); .instantiate(*ecx.tcx, ecx.tcx.mk_args(&[ecx.tcx.lifetimes.re_erased.into()]))
.skip_norm_wip();
let loc_layout = ecx.layout_of(loc_ty).unwrap(); let loc_layout = ecx.layout_of(loc_ty).unwrap();
let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); let location = ecx.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
@@ -5,7 +5,7 @@
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Variance}; use rustc_middle::ty::{Ty, TyCtxt, TypingEnv, Unnormalized, Variance};
use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::ObligationCtxt;
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
@@ -37,8 +37,8 @@ pub fn relate_types<'tcx>(
let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy();
let src = ocx.normalize(&cause, param_env, src); let src = ocx.normalize(&cause, param_env, Unnormalized::new_wip(src));
let dest = ocx.normalize(&cause, param_env, dest); let dest = ocx.normalize(&cause, param_env, Unnormalized::new_wip(dest));
match ocx.relate(&cause, param_env, variance, src, dest) { match ocx.relate(&cause, param_env, variance, src, dest) {
Ok(()) => {} Ok(()) => {}
Err(_) => return false, Err(_) => return false,
@@ -149,7 +149,9 @@ fn print_coroutine_with_kind(
) -> Result<(), PrintError> { ) -> Result<(), PrintError> {
self.print_def_path(def_id, parent_args)?; self.print_def_path(def_id, parent_args)?;
let ty::Coroutine(_, args) = self.tcx.type_of(def_id).instantiate_identity().kind() else { let ty::Coroutine(_, args) =
self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
else {
// Could be `ty::Error`. // Could be `ty::Error`.
return Ok(()); return Ok(());
}; };
+5 -3
View File
@@ -93,7 +93,8 @@ fn next(&mut self) -> Option<Self::Item> {
if self.infcx.next_trait_solver() if self.infcx.next_trait_solver()
&& let ty::Alias(..) = ty.kind() && let ty::Alias(..) = ty.kind()
{ {
let (normalized_ty, obligations) = self.structurally_normalize_ty(ty)?; let (normalized_ty, obligations) =
self.structurally_normalize_ty(Unnormalized::new_wip(ty))?;
self.state.obligations.extend(obligations); self.state.obligations.extend(obligations);
(AutoderefKind::Builtin, normalized_ty) (AutoderefKind::Builtin, normalized_ty)
} else { } else {
@@ -176,8 +177,9 @@ fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
return None; return None;
} }
let (normalized_ty, obligations) = let (normalized_ty, obligations) = self.structurally_normalize_ty(Unnormalized::new(
self.structurally_normalize_ty(Ty::new_projection(tcx, trait_target_def_id, [ty]))?; Ty::new_projection(tcx, trait_target_def_id, [ty]),
))?;
debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations); debug!("overloaded_deref_ty({:?}) = ({:?}, {:?})", ty, normalized_ty, obligations);
self.state.obligations.extend(obligations); self.state.obligations.extend(obligations);
@@ -54,7 +54,7 @@ pub(crate) fn check_drop_impl(
tcx.ensure_result().orphan_check_impl(drop_impl_did)?; tcx.ensure_result().orphan_check_impl(drop_impl_did)?;
let self_ty = tcx.type_of(drop_impl_did).instantiate_identity(); let self_ty = tcx.type_of(drop_impl_did).instantiate_identity().skip_norm_wip();
match self_ty.kind() { match self_ty.kind() {
ty::Adt(adt_def, adt_to_impl_args) => { ty::Adt(adt_def, adt_to_impl_args) => {
@@ -206,11 +206,13 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>(
// reference the params from the ADT instead of from the impl which is bad UX. To resolve // 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. // 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 impl_adt_ty = Ty::new_adt(tcx, tcx.adt_def(adt_def_id), adt_to_impl_args);
let adt_env = let adt_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args); .instantiate(tcx, adt_to_impl_args)
.skip_norm_wip();
let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id()); let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id());
let fresh_adt_ty = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_impl_args).self_ty(); let fresh_adt_ty =
tcx.impl_trait_ref(impl_def_id).instantiate(tcx, fresh_impl_args).skip_norm_wip().self_ty();
ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty) 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"); .expect("equating fully generic trait ref should never fail");
+27 -23
View File
@@ -21,7 +21,7 @@
use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::Discr;
use rustc_middle::ty::{ use rustc_middle::ty::{
AdtDef, BottomUpFolder, FnSig, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable, 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_session::lint::builtin::UNINHABITED_STATIC;
use rustc_target::spec::{AbiMap, AbiMapping}; use rustc_target::spec::{AbiMap, AbiMapping};
@@ -145,7 +145,7 @@ fn allowed_union_or_unsafe_field<'tcx>(
.lang_items() .lang_items()
.get(LangItem::BikeshedGuaranteedNoDrop) .get(LangItem::BikeshedGuaranteedNoDrop)
.unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span)); .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span));
let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else { let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) else {
tcx.dcx().span_delayed_bug(span, "could not normalize field type"); tcx.dcx().span_delayed_bug(span, "could not normalize field type");
return true; return true;
}; };
@@ -200,7 +200,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
// would be enough to check this for `extern` statics, as statics with an initializer will // 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 // have UB during initialization if they are uninhabited, but there also seems to be no good
// reason to allow any statics to be uninhabited. // reason to allow any statics to be uninhabited.
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
Ok(l) => l, Ok(l) => l,
@@ -247,7 +247,7 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
return; return;
} }
if tcx.type_of(def_id).instantiate_identity().references_error() { if tcx.type_of(def_id).instantiate_identity().skip_norm_wip().references_error() {
return; return;
} }
if check_opaque_for_cycles(tcx, def_id).is_err() { 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 // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
// here rather than using ReErased. // here rather than using ReErased.
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args); let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args).skip_norm_wip();
let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() { let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::Misc(span)), ty::ReErased => infcx.next_region_var(RegionVariableOrigin::Misc(span)),
_ => re, _ => re,
@@ -345,8 +345,10 @@ fn check_opaque_meets_bounds<'tcx>(
// HACK: We eagerly instantiate some bounds to report better errors for them... // HACK: We eagerly instantiate some bounds to report better errors for them...
// This isn't necessary for correctness, since we register these bounds when // 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. // equating the opaque below, but we should clean this up in the new solver.
for (predicate, pred_span) in for (predicate, pred_span) in tcx
tcx.explicit_item_bounds(def_id).iter_instantiated_copied(tcx, args) .explicit_item_bounds(def_id)
.iter_instantiated_copied(tcx, args)
.map(Unnormalized::skip_norm_wip)
{ {
let predicate = predicate.fold_with(&mut BottomUpFolder { let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx, 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. // These correspond to lifetime variables that never got resolved, so we patch this up here.
ty.ty = erase_re_vars(ty.ty); ty.ty = erase_re_vars(ty.ty);
// Get the hidden type. // Get the hidden type.
let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args).skip_norm_wip();
let hidden_ty = erase_re_vars(hidden_ty); let hidden_ty = erase_re_vars(hidden_ty);
// If the hidden types differ, emit a type mismatch diagnostic. // 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) { fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() { if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
if match tcx.type_of(def_id).instantiate_identity().kind() { if match tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() {
ty::RawPtr(_, _) => false, ty::RawPtr(_, _) => false,
ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args), ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
_ => true, _ => 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_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id); check_static_linkage(tcx, def_id);
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
res = res.and(wfcheck::check_static_item( res = res.and(wfcheck::check_static_item(
tcx, def_id, ty, /* should_check_for_sync */ true, 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); tcx.ensure_ok().associated_items(def_id);
if of_trait { if of_trait {
let impl_trait_header = tcx.impl_trait_header(def_id); let impl_trait_header = tcx.impl_trait_header(def_id);
res = res.and( res = res.and(tcx.ensure_result().coherent_trait(
tcx.ensure_result() impl_trait_header.trait_ref.instantiate_identity().skip_norm_wip().def_id,
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id), ));
);
if res.is_ok() { if res.is_ok() {
// Checking this only makes sense if the all trait impls satisfy basic // Checking this only makes sense if the all trait impls satisfy basic
@@ -978,7 +979,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
// //
// Changing this to normalized obligations is a breaking change: // Changing this to normalized obligations is a breaking change:
// `type Bar = [(); panic!()];` would become an error // `type Bar = [(); panic!()];` would become an error
if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty) if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty.skip_norm_wip())
{ {
let filtered_obligations = let filtered_obligations =
unnormalized_obligations.into_iter().filter(|o| { unnormalized_obligations.into_iter().filter(|o| {
@@ -1240,7 +1241,7 @@ fn check_impl_items_against_trait<'tcx>(
impl_id: LocalDefId, impl_id: LocalDefId,
impl_trait_header: ty::ImplTraitHeader<'tcx>, impl_trait_header: ty::ImplTraitHeader<'tcx>,
) { ) {
let trait_ref = impl_trait_header.trait_ref.instantiate_identity(); let trait_ref = impl_trait_header.trait_ref.instantiate_identity().skip_norm_wip();
// If the trait reference itself is erroneous (so the compilation is going // 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` // to fail), skip checking the items here -- the `impl_item` table in `tcx`
// isn't populated for such impls. // isn't populated for such impls.
@@ -1287,7 +1288,9 @@ fn check_impl_items_against_trait<'tcx>(
tcx, tcx,
ty_impl_item, ty_impl_item,
ty_trait_item, ty_trait_item,
tcx.impl_trait_ref(ty_impl_item.container_id(tcx)).instantiate_identity(), tcx.impl_trait_ref(ty_impl_item.container_id(tcx))
.instantiate_identity()
.skip_norm_wip(),
); );
} }
ty::AssocKind::Const { .. } => {} ty::AssocKind::Const { .. } => {}
@@ -1416,7 +1419,7 @@ fn check_impl_items_against_trait<'tcx>(
} }
fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
let t = tcx.type_of(def_id).instantiate_identity(); let t = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
if let ty::Adt(def, args) = t.kind() if let ty::Adt(def, args) = t.kind()
&& def.is_struct() && def.is_struct()
{ {
@@ -1491,7 +1494,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
#[tracing::instrument(skip(tcx), level = "debug")] #[tracing::instrument(skip(tcx), level = "debug")]
fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) { fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) {
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
let ty::Adt(def, args) = ty.kind() else { return }; let ty::Adt(def, args) = ty.kind() else { return };
if !def.is_struct() { if !def.is_struct() {
tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-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 { if first {
format!( format!(
"`{}` contains a field of type `{}`", "`{}` contains a field of type `{}`",
tcx.type_of(def.did()).instantiate_identity(), tcx.type_of(def.did()).instantiate_identity().skip_norm_wip(),
ident ident
) )
} else { } else {
@@ -1662,7 +1665,7 @@ pub(super) fn check_packed_inner(
def_id: DefId, def_id: DefId,
stack: &mut Vec<DefId>, stack: &mut Vec<DefId>,
) -> Option<Vec<(DefId, Span)>> { ) -> Option<Vec<(DefId, Span)>> {
if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() { if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() {
if def.is_struct() || def.is_union() { if def.is_struct() || def.is_union() {
if def.repr().align.is_some() { if def.repr().align.is_some() {
return Some(vec![(def.did(), DUMMY_SP)]); return Some(vec![(def.did(), DUMMY_SP)]);
@@ -1790,7 +1793,8 @@ fn check_unsuited<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> ControlFlow<UnsuitedInfo<'tcx>> { ) -> ControlFlow<UnsuitedInfo<'tcx>> {
// We can encounter projections during traversal, so ensure the type is normalized. // We can encounter projections during traversal, so ensure the type is normalized.
let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); let ty =
tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)).unwrap_or(ty);
match ty.kind() { match ty.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)), ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)),
ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty), ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty),
@@ -2024,7 +2028,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
return; return;
} }
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
if ty.references_error() { if ty.references_error() {
// If there is already another error, do not emit an error for not using a type parameter. // If there is already another error, do not emit an error for not using a type parameter.
return; return;
@@ -15,7 +15,7 @@
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -68,26 +68,33 @@ pub(crate) fn compare_eii_function_types<'tcx>(
let mut wf_tys = FxIndexSet::default(); let mut wf_tys = FxIndexSet::default();
let norm_cause = ObligationCause::misc(external_impl_span, external_impl); let norm_cause = ObligationCause::misc(external_impl_span, external_impl);
let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity(); let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity().skip_norm_wip();
let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig); let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig);
debug!(?declaration_sig); debug!(?declaration_sig);
let unnormalized_external_impl_sig = infcx.instantiate_binder_with_fresh_vars( let unnormalized_external_impl_sig = infcx.instantiate_binder_with_fresh_vars(
external_impl_span, external_impl_span,
infer::BoundRegionConversionTime::HigherRankedType, infer::BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(external_impl).instantiate( tcx.fn_sig(external_impl)
tcx, .instantiate(
infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()), tcx,
), infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()),
)
.skip_norm_wip(),
);
let external_impl_sig = ocx.normalize(
&norm_cause,
param_env,
Unnormalized::new_wip(unnormalized_external_impl_sig),
); );
let external_impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_external_impl_sig);
debug!(?external_impl_sig); debug!(?external_impl_sig);
// Next, add all inputs and output as well-formed tys. Importantly, // Next, add all inputs and output as well-formed tys. Importantly,
// we have to do this before normalization, since the normalized ty may // we have to do this before normalization, since the normalized ty may
// not contain the input parameters. See issue #87748. // not contain the input parameters. See issue #87748.
wf_tys.extend(declaration_sig.inputs_and_output.iter()); wf_tys.extend(declaration_sig.inputs_and_output.iter());
let declaration_sig = ocx.normalize(&norm_cause, param_env, declaration_sig); let declaration_sig =
ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(declaration_sig));
// We also have to add the normalized declaration // We also have to add the normalized declaration
// as we don't normalize during implied bounds computation. // as we don't normalize during implied bounds computation.
wf_tys.extend(external_impl_sig.inputs_and_output.iter()); wf_tys.extend(external_impl_sig.inputs_and_output.iter());
@@ -170,7 +177,7 @@ pub(crate) fn compare_eii_statics<'tcx>(
let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis()); let infcx = &tcx.infer_ctxt().build(TypingMode::non_body_analysis());
let ocx = ObligationCtxt::new_with_diagnostics(infcx); let ocx = ObligationCtxt::new_with_diagnostics(infcx);
let declaration_ty = tcx.type_of(foreign_item).instantiate_identity(); let declaration_ty = tcx.type_of(foreign_item).instantiate_identity().skip_norm_wip();
debug!(?declaration_ty); debug!(?declaration_ty);
// FIXME: Copied over from compare impl items, same issue: // FIXME: Copied over from compare impl items, same issue:
@@ -16,7 +16,7 @@
use rustc_middle::ty::{ use rustc_middle::ty::{
self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable, self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable,
TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
Upcast, Unnormalized, Upcast,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{BytePos, DUMMY_SP, Span}; use rustc_span::{BytePos, DUMMY_SP, Span};
@@ -40,7 +40,8 @@ pub(super) fn compare_impl_item(
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl_item = tcx.associated_item(impl_item_def_id); let impl_item = tcx.associated_item(impl_item_def_id);
let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?); let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?);
let impl_trait_ref = tcx.impl_trait_ref(impl_item.container_id(tcx)).instantiate_identity(); let impl_trait_ref =
tcx.impl_trait_ref(impl_item.container_id(tcx)).instantiate_identity().skip_norm_wip();
debug!(?impl_trait_ref); debug!(?impl_trait_ref);
match impl_item.kind { match impl_item.kind {
@@ -235,8 +236,9 @@ fn compare_method_predicate_entailment<'tcx>(
); );
} }
let hybrid_preds = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip);
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
// FIXME(-Zhigher-ranked-assumptions): The `hybrid_preds` // FIXME(-Zhigher-ranked-assumptions): The `hybrid_preds`
// should be well-formed. However, using them may result in // should be well-formed. However, using them may result in
// region errors as we currently don't track placeholder // region errors as we currently don't track placeholder
@@ -327,21 +329,22 @@ fn compare_method_predicate_entailment<'tcx>(
let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars( let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
impl_m_span, impl_m_span,
BoundRegionConversionTime::HigherRankedType, BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity(), tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(),
); );
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id); let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id);
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig); let impl_sig =
ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(unnormalized_impl_sig));
debug!(?impl_sig); debug!(?impl_sig);
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args); let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip();
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig); 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, // Next, add all inputs and output as well-formed tys. Importantly,
// we have to do this before normalization, since the normalized ty may // we have to do this before normalization, since the normalized ty may
// not contain the input parameters. See issue #87748. // not contain the input parameters. See issue #87748.
wf_tys.extend(trait_sig.inputs_and_output.iter()); wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_sig = ocx.normalize(&norm_cause, param_env, trait_sig); let trait_sig = ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(trait_sig));
// We also have to add the normalized trait signature // We also have to add the normalized trait signature
// as we don't normalize during implied bounds computation. // as we don't normalize during implied bounds computation.
wf_tys.extend(trait_sig.inputs_and_output.iter()); wf_tys.extend(trait_sig.inputs_and_output.iter());
@@ -463,8 +466,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> { ) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
let impl_m = tcx.associated_item(impl_m_def_id.to_def_id()); 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 trait_m = tcx.associated_item(impl_m.expect_trait_impl()?);
let impl_trait_ref = let impl_trait_ref = tcx
tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).instantiate_identity(); .impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id()))
.instantiate_identity()
.skip_norm_wip();
// First, check a few of the same things as `compare_impl_method`, // First, check a few of the same things as `compare_impl_method`,
// just so we don't ICE during instantiation later. // just so we don't ICE during instantiation later.
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
@@ -493,7 +498,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
.instantiate_identity(tcx) .instantiate_identity(tcx)
.into_iter() .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(|(clause, _)| clause); .map(|(clause, _)| clause.skip_norm_wip());
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
let param_env = traits::normalize_param_env_or_error( let param_env = traits::normalize_param_env_or_error(
tcx, tcx,
@@ -532,11 +537,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_sig = ocx.normalize( let impl_sig = ocx.normalize(
&misc_cause, &misc_cause,
param_env, param_env,
infcx.instantiate_binder_with_fresh_vars( Unnormalized::new_wip(infcx.instantiate_binder_with_fresh_vars(
return_span, return_span,
BoundRegionConversionTime::HigherRankedType, BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity(), tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(),
), )),
); );
impl_sig.error_reported()?; impl_sig.error_reported()?;
let impl_return_ty = impl_sig.output(); let impl_return_ty = impl_sig.output();
@@ -549,11 +554,12 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let unnormalized_trait_sig = tcx let unnormalized_trait_sig = tcx
.liberate_late_bound_regions( .liberate_late_bound_regions(
impl_m.def_id, impl_m.def_id,
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args), tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip(),
) )
.fold_with(&mut collector); .fold_with(&mut collector);
let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig); let trait_sig =
ocx.normalize(&misc_cause, param_env, Unnormalized::new_wip(unnormalized_trait_sig));
trait_sig.error_reported()?; trait_sig.error_reported()?;
let trait_return_ty = trait_sig.output(); let trait_return_ty = trait_sig.output();
@@ -839,12 +845,13 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
.cx() .cx()
.explicit_item_bounds(def_id) .explicit_item_bounds(def_id)
.iter_instantiated_copied(self.cx(), proj_args) .iter_instantiated_copied(self.cx(), proj_args)
.map(Unnormalized::skip_norm_wip)
{ {
let pred = pred.fold_with(self); let pred = pred.fold_with(self);
let pred = self.ocx.normalize( let pred = self.ocx.normalize(
&ObligationCause::misc(self.span, self.body_id), &ObligationCause::misc(self.span, self.body_id),
self.param_env, self.param_env,
pred, Unnormalized::new_wip(pred),
); );
self.ocx.register_obligation(traits::Obligation::new( self.ocx.register_obligation(traits::Obligation::new(
@@ -1252,11 +1259,11 @@ fn check_region_late_boundedness<'tcx>(
.build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id)); .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_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id);
let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args); let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args).skip_norm_wip();
let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig); let 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_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id);
let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args); let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args).skip_norm_wip();
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig); let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@@ -1443,7 +1450,7 @@ fn find_region_in_predicates<'tcx>(
early_bound_region: ty::Region<'tcx>, early_bound_region: ty::Region<'tcx>,
) -> Option<Span> { ) -> Option<Span> {
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) {
if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() { if pred.skip_norm_wip().visit_with(&mut FindRegion(early_bound_region)).is_break() {
return Some(span); return Some(span);
} }
} }
@@ -1508,7 +1515,7 @@ fn compare_self_type<'tcx>(
} }
ty::AssocContainer::Trait => tcx.types.self_param, ty::AssocContainer::Trait => tcx.types.self_param,
}; };
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0); let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip().input(0);
let (infcx, param_env) = tcx let (infcx, param_env) = tcx
.infer_ctxt() .infer_ctxt()
.build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id)); .build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id));
@@ -2111,7 +2118,7 @@ fn compare_generic_param_kinds<'tcx>(
format!( format!(
"{} const parameter of type `{}`", "{} const parameter of type `{}`",
prefix, prefix,
tcx.type_of(param.def_id).instantiate_identity() tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip()
) )
} }
Type { .. } => format!("{prefix} type parameter"), Type { .. } => format!("{prefix} type parameter"),
@@ -2227,8 +2234,9 @@ fn compare_const_predicate_entailment<'tcx>(
.instantiate_own(tcx, trait_to_impl_args) .instantiate_own(tcx, trait_to_impl_args)
.map(|(predicate, _)| predicate), .map(|(predicate, _)| predicate),
); );
let hybrid_preds = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip);
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
let param_env = traits::normalize_param_env_or_error( let param_env = traits::normalize_param_env_or_error(
tcx, tcx,
param_env, param_env,
@@ -2379,7 +2387,8 @@ fn compare_type_predicate_entailment<'tcx>(
); );
} }
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds)); let hybrid_preds = hybrid_preds.into_iter().map(Unnormalized::skip_norm_wip);
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
debug!(caller_bounds=?param_env.caller_bounds()); debug!(caller_bounds=?param_env.caller_bounds());
@@ -2511,12 +2520,13 @@ pub(super) fn check_type_bounds<'tcx>(
let mut obligations: Vec<_> = util::elaborate( let mut obligations: Vec<_> = util::elaborate(
tcx, tcx,
tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map( tcx.explicit_item_bounds(trait_ty.def_id)
|(concrete_ty_bound, span)| { .iter_instantiated_copied(tcx, rebased_args)
.map(Unnormalized::skip_norm_wip)
.map(|(concrete_ty_bound, span)| {
debug!(?concrete_ty_bound); debug!(?concrete_ty_bound);
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
}, }),
),
) )
.collect(); .collect();
@@ -2526,6 +2536,7 @@ pub(super) fn check_type_bounds<'tcx>(
tcx, tcx,
tcx.explicit_implied_const_bounds(trait_ty.def_id) tcx.explicit_implied_const_bounds(trait_ty.def_id)
.iter_instantiated_copied(tcx, rebased_args) .iter_instantiated_copied(tcx, rebased_args)
.map(Unnormalized::skip_norm_wip)
.map(|(c, span)| { .map(|(c, span)| {
traits::Obligation::new( traits::Obligation::new(
tcx, tcx,
@@ -2544,7 +2555,11 @@ pub(super) fn check_type_bounds<'tcx>(
// See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>. // See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
for obligation in &mut obligations { for obligation in &mut obligations {
match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) { match ocx.deeply_normalize(
&normalize_cause,
normalize_param_env,
Unnormalized::new_wip(obligation.predicate),
) {
Ok(pred) => obligation.predicate = pred, Ok(pred) => obligation.predicate = pred,
Err(e) => { Err(e) => {
return Err(infcx.err_ctxt().report_fulfillment_errors(e)); return Err(infcx.err_ctxt().report_fulfillment_errors(e));
@@ -2702,7 +2717,7 @@ fn param_env_with_gat_bounds<'tcx>(
// checking the default value specifically here. Add this equality to the // checking the default value specifically here. Add this equality to the
// ParamEnv for normalization specifically. // ParamEnv for normalization specifically.
let normalize_impl_ty = let normalize_impl_ty =
tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args); tcx.type_of(impl_ty.def_id).instantiate(tcx, normalize_impl_ty_args).skip_norm_wip();
let rebased_args = let rebased_args =
normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args); normalize_impl_ty_args.rebase_onto(tcx, container_id, impl_trait_ref.args);
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
@@ -9,7 +9,7 @@
use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, TypingMode, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized,
}; };
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::regions::InferCtxtRegionExt; 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_def_id = impl_m.container_id(tcx);
let impl_m_args = ty::GenericArgs::identity_for_item(tcx, impl_m.def_id); 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 trait_m_to_impl_m_args = impl_m_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args);
let bound_trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args); let bound_trait_m_sig =
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args).skip_norm_wip();
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, bound_trait_m_sig); 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. // 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( let trait_m_sig_with_self_for_diag = tcx.liberate_late_bound_regions(
impl_m.def_id, impl_m.def_id,
tcx.fn_sig(trait_m.def_id).instantiate( tcx.fn_sig(trait_m.def_id)
tcx, .instantiate(
tcx.mk_args_from_iter( tcx,
[tcx.types.self_param.into()] tcx.mk_args_from_iter(
.into_iter() [tcx.types.self_param.into()]
.chain(trait_m_to_impl_m_args.iter().skip(1)), .into_iter()
), .chain(trait_m_to_impl_m_args.iter().skip(1)),
), ),
)
.skip_norm_wip(),
); );
let Ok(hidden_tys) = tcx.collect_return_position_impl_trait_in_trait_tys(impl_m.def_id) else { 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() { 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 impl_opaque_args = trait_projection.args.rebase_onto(tcx, trait_m.def_id, impl_m_args);
let hidden_ty = let hidden_ty = hidden_tys[&trait_projection.kind.def_id()]
hidden_tys[&trait_projection.kind.def_id()].instantiate(tcx, impl_opaque_args); .instantiate(tcx, impl_opaque_args)
.skip_norm_wip();
// If the hidden type is not an opaque, then we have "refined" the trait signature. // If the hidden type is not an opaque, then we have "refined" the trait signature.
let ty::Alias( let ty::Alias(
@@ -121,12 +125,14 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
trait_bounds.extend( trait_bounds.extend(
tcx.item_bounds(trait_projection.kind.def_id()) tcx.item_bounds(trait_projection.kind.def_id())
.iter_instantiated(tcx, trait_projection.args), .iter_instantiated(tcx, trait_projection.args)
.map(Unnormalized::skip_norm_wip),
); );
impl_bounds.extend(elaborate( impl_bounds.extend(elaborate(
tcx, tcx,
tcx.explicit_item_bounds(impl_opaque_def_id) tcx.explicit_item_bounds(impl_opaque_def_id)
.iter_instantiated_copied(tcx, impl_opaque.args), .iter_instantiated_copied(tcx, impl_opaque.args)
.map(Unnormalized::skip_norm_wip),
)); ));
pairs.push((trait_projection, impl_opaque)); pairs.push((trait_projection, impl_opaque));
@@ -137,7 +143,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
.instantiate_identity(tcx) .instantiate_identity(tcx)
.into_iter() .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(|(clause, _)| clause); .map(|(clause, _)| clause.skip_norm_wip());
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds)); 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()); let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy());
@@ -152,9 +158,11 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
// 2. Deeply normalize any other projections that show up in the bound. That makes sure // 2. Deeply normalize any other projections that show up in the bound. That makes sure
// that we don't consider `tests/ui/async-await/in-trait/async-associated-types.rs` // that we don't consider `tests/ui/async-await/in-trait/async-associated-types.rs`
// or `tests/ui/impl-trait/in-trait/refine-normalize.rs` to be refining. // or `tests/ui/impl-trait/in-trait/refine-normalize.rs` to be refining.
let Ok((trait_bounds, impl_bounds)) = let Ok((trait_bounds, impl_bounds)) = ocx.deeply_normalize(
ocx.deeply_normalize(&ObligationCause::dummy(), param_env, (trait_bounds, impl_bounds)) &ObligationCause::dummy(),
else { param_env,
Unnormalized::new_wip((trait_bounds, impl_bounds)),
) else {
tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)");
return; return;
}; };
@@ -168,7 +176,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
implied_wf_types.extend(ocx.normalize( implied_wf_types.extend(ocx.normalize(
&ObligationCause::dummy(), &ObligationCause::dummy(),
param_env, param_env,
trait_m_sig.inputs_and_output, Unnormalized::new_wip(trait_m_sig.inputs_and_output),
)); ));
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)"); tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)");
@@ -267,6 +275,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
.tcx .tcx
.explicit_item_bounds(def_id) .explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, proj.args) .iter_instantiated_copied(self.tcx, proj.args)
.map(Unnormalized::skip_norm_wip)
{ {
pred.visit_with(self); pred.visit_with(self);
} }
@@ -320,6 +329,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
let Some(future_output_ty) = tcx let Some(future_output_ty) = tcx
.explicit_item_bounds(future_ty_def_id) .explicit_item_bounds(future_ty_def_id)
.iter_instantiated_copied(tcx, args) .iter_instantiated_copied(tcx, args)
.map(Unnormalized::skip_norm_wip)
.find_map(|(clause, _)| match clause.kind().no_bound_vars()? { .find_map(|(clause, _)| match clause.kind().no_bound_vars()? {
ty::ClauseKind::Projection(proj) => proj.term.as_type(), ty::ClauseKind::Projection(proj) => proj.term.as_type(),
_ => None, _ => None,
@@ -4,7 +4,7 @@
use rustc_hir::{Node, find_attr}; use rustc_hir::{Node, find_attr};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized};
use rustc_session::config::EntryFnType; use rustc_session::config::EntryFnType;
use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_span::{ErrorGuaranteed, Span}; use rustc_span::{ErrorGuaranteed, Span};
@@ -23,12 +23,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> { fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) -> Result<(), ErrorGuaranteed> {
let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity(); let main_fnsig = tcx.fn_sig(main_def_id).instantiate_identity().skip_norm_wip();
let main_span = tcx.def_span(main_def_id); let main_span = tcx.def_span(main_def_id);
fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId { fn main_fn_diagnostics_def_id(tcx: TyCtxt<'_>, def_id: DefId, sp: Span) -> LocalDefId {
if let Some(local_def_id) = def_id.as_local() { if let Some(local_def_id) = def_id.as_local() {
let hir_type = tcx.type_of(local_def_id).instantiate_identity(); let hir_type = tcx.type_of(local_def_id).instantiate_identity().skip_norm_wip();
if !matches!(hir_type.kind(), ty::FnDef(..)) { if !matches!(hir_type.kind(), ty::FnDef(..)) {
span_bug!(sp, "main has a non-function type: found `{}`", hir_type); span_bug!(sp, "main has a non-function type: found `{}`", hir_type);
} }
@@ -129,7 +129,7 @@ fn main_fn_return_type_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
ObligationCauseCode::MainFunctionType, ObligationCauseCode::MainFunctionType,
); );
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty); let norm_return_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(return_ty));
ocx.register_bound(cause, param_env, norm_return_ty, term_did); ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.evaluate_obligations_error_on_ambiguity(); let errors = ocx.evaluate_obligations_error_on_ambiguity();
if !errors.is_empty() { if !errors.is_empty() {
@@ -277,7 +277,7 @@ pub(crate) fn check_intrinsic_type(
kind: ty::BoundRegionKind::ClosureEnv, kind: ty::BoundRegionKind::ClosureEnv,
}, },
); );
let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]); let va_list_ty = tcx.type_of(did).instantiate(tcx, &[region.into()]).skip_norm_wip();
(Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty) (Ty::new_ref(tcx, env_region, va_list_ty, mutbl), va_list_ty)
}; };
+11 -5
View File
@@ -89,6 +89,7 @@
use rustc_middle::ty::print::with_types_for_signature; use rustc_middle::ty::print::with_types_for_signature;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, GenericArgs, GenericArgsRef, OutlivesPredicate, Region, Ty, TyCtxt, TypingMode, self, GenericArgs, GenericArgsRef, OutlivesPredicate, Region, Ty, TyCtxt, TypingMode,
Unnormalized,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
@@ -238,7 +239,7 @@ fn missing_items_err(
let snippet = with_types_for_signature!(suggestion_signature( let snippet = with_types_for_signature!(suggestion_signature(
tcx, tcx,
trait_item, trait_item,
tcx.impl_trait_ref(impl_def_id).instantiate_identity(), tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip(),
)); ));
let code = format!("{padding}{snippet}\n{padding}"); let code = format!("{padding}{snippet}\n{padding}");
if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) { 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 && let Some(output) = tcx
.explicit_item_self_bounds(alias_ty.kind.def_id()) .explicit_item_self_bounds(alias_ty.kind.def_id())
.iter_instantiated_copied(tcx, alias_ty.args) .iter_instantiated_copied(tcx, alias_ty.args)
.map(Unnormalized::skip_norm_wip)
.find_map(|(bound, _)| { .find_map(|(bound, _)| {
bound.as_projection_clause()?.no_bound_vars()?.term.as_type() bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
}) { }) {
@@ -536,22 +538,26 @@ fn suggestion_signature<'tcx>(
tcx, tcx,
tcx.liberate_late_bound_regions( tcx.liberate_late_bound_regions(
assoc.def_id, assoc.def_id,
tcx.fn_sig(assoc.def_id).instantiate(tcx, args), tcx.fn_sig(assoc.def_id).instantiate(tcx, args).skip_norm_wip(),
), ),
assoc.ident(tcx), assoc.ident(tcx),
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), tcx.predicates_of(assoc.def_id)
.instantiate_own(tcx, args)
.map(|(c, s)| (c.skip_norm_wip(), s)),
assoc, assoc,
), ),
ty::AssocKind::Type { .. } => { ty::AssocKind::Type { .. } => {
let (generics, where_clauses) = bounds_from_generic_predicates( let (generics, where_clauses) = bounds_from_generic_predicates(
tcx, tcx,
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), tcx.predicates_of(assoc.def_id)
.instantiate_own(tcx, args)
.map(|(c, s)| (c.skip_norm_wip(), s)),
assoc, assoc,
); );
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name()) format!("type {}{generics} = /* Type */{where_clauses};", assoc.name())
} }
ty::AssocKind::Const { name, .. } => { ty::AssocKind::Const { name, .. } => {
let ty = tcx.type_of(assoc.def_id).instantiate_identity(); let ty = tcx.type_of(assoc.def_id).instantiate_identity().skip_norm_wip();
let val = tcx let val = tcx
.infer_ctxt() .infer_ctxt()
.build(TypingMode::non_body_analysis()) .build(TypingMode::non_body_analysis())
@@ -24,7 +24,7 @@
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags, self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags,
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
Upcast, Unnormalized, Upcast,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
@@ -109,7 +109,7 @@ pub(super) fn deeply_normalize<T>(
Ok(value) => value, Ok(value) => value,
Err(errors) => { Err(errors) => {
self.infcx.err_ctxt().report_fulfillment_errors(errors); self.infcx.err_ctxt().report_fulfillment_errors(errors);
value value.skip_norm_wip()
} }
} }
} else { } else {
@@ -426,7 +426,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from. // `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions( let sig: ty::FnSig<'_> = tcx.liberate_late_bound_regions(
item_def_id.to_def_id(), item_def_id.to_def_id(),
tcx.fn_sig(item_def_id).instantiate_identity(), tcx.fn_sig(item_def_id).instantiate_identity().skip_norm_wip(),
); );
gather_gat_bounds( gather_gat_bounds(
tcx, tcx,
@@ -456,6 +456,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
item_def_id, item_def_id,
tcx.explicit_item_bounds(item_def_id) tcx.explicit_item_bounds(item_def_id)
.iter_identity_copied() .iter_identity_copied()
.map(Unnormalized::skip_norm_wip)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&FxIndexSet::default(), &FxIndexSet::default(),
gat_def_id, gat_def_id,
@@ -850,7 +851,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &ty::GenericParamDef) -> Result<(), Er
// Const parameters are well formed if their type is structural match. // Const parameters are well formed if their type is structural match.
ty::GenericParamDefKind::Const { .. } => { ty::GenericParamDefKind::Const { .. } => {
let ty = tcx.type_of(param.def_id).instantiate_identity(); let ty = tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip();
let span = tcx.def_span(param.def_id); let span = tcx.def_span(param.def_id);
let def_id = param.def_id.expect_local(); let def_id = param.def_id.expect_local();
@@ -975,7 +976,7 @@ pub(crate) fn check_associated_item(
let self_ty = match item.container { let self_ty = match item.container {
ty::AssocContainer::Trait => tcx.types.self_param, ty::AssocContainer::Trait => tcx.types.self_param,
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => { ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
tcx.type_of(item.container_id(tcx)).instantiate_identity() tcx.type_of(item.container_id(tcx)).instantiate_identity().skip_norm_wip()
} }
}; };
@@ -1005,7 +1006,7 @@ pub(crate) fn check_associated_item(
Ok(()) Ok(())
} }
ty::AssocKind::Fn { .. } => { ty::AssocKind::Fn { .. } => {
let sig = tcx.fn_sig(def_id).instantiate_identity(); let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let hir_sig = let hir_sig =
tcx.hir_node_by_def_id(def_id).fn_sig().expect("bad signature for method"); 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); check_fn_or_method(wfcx, sig, hir_sig.decl, def_id);
@@ -1094,7 +1095,7 @@ fn check_type_defn<'tcx>(
// intermediate types must be sized. // intermediate types must be sized.
let needs_drop_copy = || { let needs_drop_copy = || {
packed && { packed && {
let ty = tcx.type_of(variant.tail().did).instantiate_identity(); let ty = tcx.type_of(variant.tail().did).instantiate_identity().skip_norm_wip();
let ty = tcx.erase_and_anonymize_regions(ty); let ty = tcx.erase_and_anonymize_regions(ty);
assert!(!ty.has_infer()); assert!(!ty.has_infer());
ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env)) ty.needs_drop(tcx, wfcx.infcx.typing_env(wfcx.param_env))
@@ -1201,15 +1202,17 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); let bounds = wfcx.tcx().explicit_item_bounds(item.def_id);
debug!("check_associated_type_bounds: bounds={:?}", bounds); debug!("check_associated_type_bounds: bounds={:?}", bounds);
let wf_obligations = bounds.iter_identity_copied().flat_map(|(bound, bound_span)| { let wf_obligations = bounds.iter_identity_copied().map(Unnormalized::skip_norm_wip).flat_map(
traits::wf::clause_obligations( |(bound, bound_span)| {
wfcx.infcx, traits::wf::clause_obligations(
wfcx.param_env, wfcx.infcx,
wfcx.body_def_id, wfcx.param_env,
bound, wfcx.body_def_id,
bound_span, bound,
) bound_span,
}); )
},
);
wfcx.register_obligations(wf_obligations); wfcx.register_obligations(wf_obligations);
} }
@@ -1222,7 +1225,7 @@ fn check_item_fn(
enter_wf_checking_ctxt(tcx, def_id, |wfcx| { enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
check_eiis_fn(tcx, def_id); check_eiis_fn(tcx, def_id);
let sig = tcx.fn_sig(def_id).instantiate_identity(); let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
check_fn_or_method(wfcx, sig, decl, def_id); check_fn_or_method(wfcx, sig, decl, def_id);
Ok(()) Ok(())
}) })
@@ -1296,14 +1299,14 @@ pub(crate) fn check_static_item<'tcx>(
let span = tcx.ty_span(item_id); let span = tcx.ty_span(item_id);
let loc = Some(WellFormedLoc::Ty(item_id)); let loc = Some(WellFormedLoc::Ty(item_id));
let item_ty = wfcx.deeply_normalize(span, loc, ty); let item_ty = wfcx.deeply_normalize(span, loc, Unnormalized::new_wip(ty));
let is_foreign_item = tcx.is_foreign_item(item_id); let is_foreign_item = tcx.is_foreign_item(item_id);
let is_structurally_foreign_item = || { let is_structurally_foreign_item = || {
let tail = tcx.struct_tail_raw( let tail = tcx.struct_tail_raw(
item_ty, item_ty,
&ObligationCause::dummy(), &ObligationCause::dummy(),
|ty| wfcx.deeply_normalize(span, loc, ty), |ty| wfcx.deeply_normalize(span, loc, Unnormalized::new_wip(ty)),
|| {}, || {},
); );
@@ -1395,7 +1398,7 @@ fn check_impl<'tcx>(
let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(item.owner_id).instantiate_identity();
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in
// case other `Foo` impls are incoherent. // case other `Foo` impls are incoherent.
tcx.ensure_result().coherent_trait(trait_ref.def_id)?; tcx.ensure_result().coherent_trait(trait_ref.skip_normalization().def_id)?;
let trait_span = of_trait.trait_ref.path.span; let trait_span = of_trait.trait_ref.path.span;
let trait_ref = wfcx.deeply_normalize( let trait_ref = wfcx.deeply_normalize(
trait_span, trait_span,
@@ -1456,11 +1459,11 @@ fn check_impl<'tcx>(
wfcx.register_obligations(obligations); wfcx.register_obligations(obligations);
} }
None => { None => {
let self_ty = tcx.type_of(item.owner_id).instantiate_identity(); let self_ty = tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip();
let self_ty = wfcx.deeply_normalize( let self_ty = wfcx.deeply_normalize(
item.span, item.span,
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
self_ty, Unnormalized::new_wip(self_ty),
); );
wfcx.register_wf_obligation( wfcx.register_wf_obligation(
impl_.self_ty.span, impl_.self_ty.span,
@@ -1491,7 +1494,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. // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
for param in &generics.own_params { for param in &generics.own_params {
if let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity) { if let Some(default) = param
.default_value(tcx)
.map(ty::EarlyBinder::instantiate_identity)
.map(Unnormalized::skip_norm_wip)
{
// Ignore dependent defaults -- that is, where the default of one type // Ignore dependent defaults -- that is, where the default of one type
// parameter includes another (e.g., `<T, U = T>`). In those cases, we can't // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
// be sure if it will error or not as user might always specify the other. // be sure if it will error or not as user might always specify the other.
@@ -1519,14 +1526,14 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id:
ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => continue, ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => continue,
ty::ConstKind::Value(cv) => cv.ty, ty::ConstKind::Value(cv) => cv.ty,
ty::ConstKind::Unevaluated(uv) => { ty::ConstKind::Unevaluated(uv) => {
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args).skip_norm_wip()
} }
ty::ConstKind::Param(param_ct) => { ty::ConstKind::Param(param_ct) => {
param_ct.find_const_ty_from_env(wfcx.param_env) param_ct.find_const_ty_from_env(wfcx.param_env)
} }
}; };
let param_ty = tcx.type_of(param.def_id).instantiate_identity(); let param_ty = tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip();
if !ct_ty.has_param() && !param_ty.has_param() { if !ct_ty.has_param() && !param_ty.has_param() {
let cause = traits::ObligationCause::new( let cause = traits::ObligationCause::new(
tcx.def_span(param.def_id), tcx.def_span(param.def_id),
@@ -1555,7 +1562,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, _| { let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| {
if param.index >= generics.parent_count as u32 if param.index >= generics.parent_count as u32
// If the param has a default, ... // If the param has a default, ...
&& let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity) && let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity).map(Unnormalized::skip_norm_wip)
// ... and it's not a dependent default, ... // ... and it's not a dependent default, ...
&& !default.has_param() && !default.has_param()
{ {
@@ -1599,12 +1606,16 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args); let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args);
// Don't check non-defaulted params, dependent defaults (including lifetimes) // Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params. // or preds with multiple params.
if instantiated_pred.has_non_region_param() if instantiated_pred.skip_normalization().has_non_region_param()
|| param_count.params.len() > 1 || param_count.params.len() > 1
|| has_region || has_region
{ {
None None
} else if predicates.predicates.iter().any(|&(p, _)| p == instantiated_pred) { } else if predicates
.predicates
.iter()
.any(|&(p, _)| Unnormalized::new_wip(p) == instantiated_pred)
{
// Avoid duplication of predicates that contain no parameters, for example. // Avoid duplication of predicates that contain no parameters, for example.
None None
} else { } else {
@@ -1638,13 +1649,15 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
.copied() .copied()
.zip(predicates.spans.iter().copied()) .zip(predicates.spans.iter().copied())
.filter_map(|(clause, sp)| { .filter_map(|(clause, sp)| {
let clause = clause.skip_norm_wip();
let proj = clause.as_projection_clause()?; let proj = clause.as_projection_clause()?;
let pred_binder = proj let pred_binder = proj
.map_bound(|pred| { .map_bound(|pred| {
pred.term.as_const().map(|ct| { pred.term.as_const().map(|ct| {
let assoc_const_ty = tcx let assoc_const_ty = tcx
.type_of(pred.projection_term.def_id) .type_of(pred.projection_term.def_id)
.instantiate(tcx, pred.projection_term.args); .instantiate(tcx, pred.projection_term.args)
.skip_norm_wip();
ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty) ty::ClauseKind::ConstArgHasType(ct, assoc_const_ty)
}) })
}) })
@@ -1662,7 +1675,13 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
assert_eq!(predicates.predicates.len(), predicates.spans.len()); assert_eq!(predicates.predicates.len(), predicates.spans.len());
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp) traits::wf::clause_obligations(
infcx,
wfcx.param_env,
wfcx.body_def_id,
p.skip_norm_wip(),
sp,
)
}); });
let obligations: Vec<_> = let obligations: Vec<_> =
wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect(); wf_obligations.chain(default_obligations).chain(assoc_const_obligations).collect();
@@ -1697,7 +1716,7 @@ fn check_fn_or_method<'tcx>(
// one greater than the index of the last input type. // one greater than the index of the last input type.
param_idx: idx, param_idx: idx,
}), }),
ty, Unnormalized::new_wip(ty),
) )
})); }));
@@ -1783,16 +1802,16 @@ fn check_method_receiver<'tcx>(
let span = fn_sig.decl.inputs[0].span; let span = fn_sig.decl.inputs[0].span;
let loc = Some(WellFormedLoc::Param { function: method.def_id.expect_local(), param_idx: 0 }); let loc = Some(WellFormedLoc::Param { function: method.def_id.expect_local(), param_idx: 0 });
let sig = tcx.fn_sig(method.def_id).instantiate_identity(); let sig = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip();
let sig = tcx.liberate_late_bound_regions(method.def_id, sig); let sig = tcx.liberate_late_bound_regions(method.def_id, sig);
let sig = wfcx.normalize(DUMMY_SP, loc, sig); let sig = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(sig));
debug!("check_method_receiver: sig={:?}", sig); debug!("check_method_receiver: sig={:?}", sig);
let self_ty = wfcx.normalize(DUMMY_SP, loc, self_ty); let self_ty = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(self_ty));
let receiver_ty = sig.inputs()[0]; let receiver_ty = sig.inputs()[0];
let receiver_ty = wfcx.normalize(DUMMY_SP, loc, receiver_ty); let receiver_ty = wfcx.normalize(DUMMY_SP, loc, Unnormalized::new_wip(receiver_ty));
// If the receiver already has errors reported, consider it valid to avoid // If the receiver already has errors reported, consider it valid to avoid
// unnecessary errors (#58712). // unnecessary errors (#58712).
@@ -2126,6 +2145,7 @@ pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: Loc
if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx
.type_of(def_id) .type_of(def_id)
.instantiate_identity() .instantiate_identity()
.skip_norm_wip()
.visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() })
{ {
continue; continue;
@@ -2157,7 +2177,11 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
ty::Adt(def, _) => { ty::Adt(def, _) => {
if self.seen.insert(def.did()) { if self.seen.insert(def.did()) {
for field in def.all_fields() { for field in def.all_fields() {
self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?; self.tcx
.type_of(field.did)
.instantiate_identity()
.skip_norm_wip()
.visit_with(self)?;
} }
} }
} }
@@ -2278,11 +2302,15 @@ fn visit_def(&mut self, def_id: DefId) -> ControlFlow<(), ()> {
match self.tcx.def_kind(def_id) { match self.tcx.def_kind(def_id) {
DefKind::Struct | DefKind::Enum | DefKind::Union => { DefKind::Struct | DefKind::Enum | DefKind::Union => {
self.tcx.adt_def(def_id).all_fields().try_for_each(|field| { self.tcx.adt_def(def_id).all_fields().try_for_each(|field| {
self.tcx.type_of(field.did).instantiate_identity().visit_with(self) self.tcx
.type_of(field.did)
.instantiate_identity()
.skip_norm_wip()
.visit_with(self)
}) })
} }
DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => { DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => {
self.tcx.type_of(def_id).instantiate_identity().visit_with(self) self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().visit_with(self)
} }
_ => ControlFlow::Continue(()), _ => ControlFlow::Continue(()),
} }
@@ -2368,7 +2396,7 @@ fn check_false_global_bounds(&mut self) {
// Match the existing behavior. // Match the existing behavior.
if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) { if pred.is_global() && !pred.has_type_flags(TypeFlags::HAS_BINDER_VARS) {
let pred = self.normalize(span, None, pred); let pred = self.normalize(span, None, Unnormalized::new_wip(pred));
// only use the span of the predicate clause (#90869) // only use the span of the predicate clause (#90869)
let hir_node = tcx.hir_node_by_def_id(self.body_def_id); let hir_node = tcx.hir_node_by_def_id(self.body_def_id);
@@ -2483,8 +2511,13 @@ fn lint_redundant_lifetimes<'tcx>(
); );
// If we are in a function, add its late-bound lifetimes too. // If we are in a function, add its late-bound lifetimes too.
if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) { if matches!(def_kind, DefKind::Fn | DefKind::AssocFn) {
for (idx, var) in for (idx, var) in tcx
tcx.fn_sig(owner_id).instantiate_identity().bound_vars().iter().enumerate() .fn_sig(owner_id)
.instantiate_identity()
.skip_norm_wip()
.bound_vars()
.iter()
.enumerate()
{ {
let ty::BoundVariableKind::Region(kind) = var else { continue }; let ty::BoundVariableKind::Region(kind) = var else { continue };
let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind); let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
@@ -73,7 +73,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran
let tcx = checker.tcx; let tcx = checker.tcx;
let impl_did = checker.impl_def_id; let impl_did = checker.impl_def_id;
// Destructors only work on local ADT types. // Destructors only work on local ADT types.
match checker.impl_header.trait_ref.instantiate_identity().self_ty().kind() { match checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty().kind() {
ty::Adt(def, _) if def.did().is_local() => return Ok(()), ty::Adt(def, _) if def.did().is_local() => return Ok(()),
ty::Error(_) => return Ok(()), ty::Error(_) => return Ok(()),
_ => {} _ => {}
@@ -93,7 +93,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
let impl_did = checker.impl_def_id; let impl_did = checker.impl_def_id;
debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
let param_env = tcx.param_env(impl_did); let param_env = tcx.param_env(impl_did);
@@ -142,7 +142,7 @@ fn visit_implementation_of_unpin(checker: &Checker<'_>) -> Result<(), ErrorGuara
let impl_did = checker.impl_def_id; let impl_did = checker.impl_def_id;
debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did); debug!("visit_implementation_of_unpin: impl_did={:?}", impl_did);
let self_type = impl_header.trait_ref.instantiate_identity().self_ty(); let self_type = impl_header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
debug!("visit_implementation_of_unpin: self_type={:?}", self_type); debug!("visit_implementation_of_unpin: self_type={:?}", self_type);
let span = tcx.def_span(impl_did); let span = tcx.def_span(impl_did);
@@ -175,7 +175,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
let tcx = checker.tcx; let tcx = checker.tcx;
let header = checker.impl_header; let header = checker.impl_header;
let impl_did = checker.impl_def_id; let impl_did = checker.impl_def_id;
let self_type = header.trait_ref.instantiate_identity().self_ty(); let self_type = header.trait_ref.instantiate_identity().skip_norm_wip().self_ty();
assert!(!self_type.has_escaping_bound_vars()); assert!(!self_type.has_escaping_bound_vars());
let param_env = tcx.param_env(impl_did); let param_env = tcx.param_env(impl_did);
@@ -259,7 +259,7 @@ fn is_from_coerce_pointee_derive(tcx: TyCtxt<'_>, span: Span) -> bool {
fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
let tcx = checker.tcx; let tcx = checker.tcx;
let impl_did = checker.impl_def_id; let impl_did = checker.impl_def_id;
let trait_ref = checker.impl_header.trait_ref.instantiate_identity(); let trait_ref = checker.impl_header.trait_ref.instantiate_identity().skip_norm_wip();
debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
let span = tcx.def_span(impl_did); let span = tcx.def_span(impl_did);
@@ -350,7 +350,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
ty::TypingEnv::non_body_analysis(tcx, def_a.did()), ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
unnormalized_ty, unnormalized_ty,
) )
.unwrap_or(unnormalized_ty) .unwrap_or(unnormalized_ty.skip_norm_wip())
.is_phantom_data() .is_phantom_data()
{ {
return None; return None;
@@ -445,8 +445,8 @@ pub(crate) fn coerce_unsized_info<'tcx>(
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span); let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, span);
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span); let unsize_trait = tcx.require_lang_item(LangItem::Unsize, span);
let source = tcx.type_of(impl_did).instantiate_identity(); let source = tcx.type_of(impl_did).instantiate_identity().skip_norm_wip();
let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).instantiate_identity().skip_norm_wip();
assert_eq!(trait_ref.def_id, coerce_unsized_trait); assert_eq!(trait_ref.def_id, coerce_unsized_trait);
let target = trait_ref.args.type_at(1); let target = trait_ref.args.type_at(1);
@@ -570,7 +570,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
ty::TypingEnv::non_body_analysis(tcx, def_a.did()), ty::TypingEnv::non_body_analysis(tcx, def_a.did()),
unnormalized_ty, unnormalized_ty,
) )
.unwrap_or(unnormalized_ty) .unwrap_or(unnormalized_ty.skip_norm_wip())
.is_phantom_data() .is_phantom_data()
{ {
return None; return None;
@@ -788,7 +788,8 @@ fn visit_implementation_of_coerce_pointee_validity(
checker: &Checker<'_>, checker: &Checker<'_>,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let tcx = checker.tcx; let tcx = checker.tcx;
let self_ty = tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().self_ty(); let self_ty =
tcx.impl_trait_ref(checker.impl_def_id).instantiate_identity().skip_norm_wip().self_ty();
let span = tcx.def_span(checker.impl_def_id); let span = tcx.def_span(checker.impl_def_id);
if !tcx.is_builtin_derived(checker.impl_def_id.into()) { if !tcx.is_builtin_derived(checker.impl_def_id.into()) {
return Err(tcx.dcx().emit_err(errors::CoercePointeeNoUserValidityAssertion { span })); return Err(tcx.dcx().emit_err(errors::CoercePointeeNoUserValidityAssertion { span }));
@@ -164,7 +164,7 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
let id = id.owner_id.def_id; let id = id.owner_id.def_id;
let item_span = self.tcx.def_span(id); let item_span = self.tcx.def_span(id);
let self_ty = self.tcx.type_of(id).instantiate_identity(); let self_ty = self.tcx.type_of(id).instantiate_identity().skip_norm_wip();
let mut self_ty = self.tcx.peel_off_free_alias_tys(self_ty); 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. // 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. // FIXME(pattern_types): Figure out the exact coherence rules we want here.
@@ -172,7 +172,7 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
for &impl_def_id in impls { for &impl_def_id in impls {
let impl_header = tcx.impl_trait_header(impl_def_id); let impl_header = tcx.impl_trait_header(impl_def_id);
let trait_ref = impl_header.trait_ref.instantiate_identity(); let trait_ref = impl_header.trait_ref.instantiate_identity().skip_norm_wip();
let trait_def = tcx.trait_def(trait_ref.def_id); let trait_def = tcx.trait_def(trait_ref.def_id);
res = res res = res
@@ -7,6 +7,7 @@
use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
Unnormalized,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::{DefId, LocalDefId};
@@ -22,7 +23,7 @@ pub(crate) fn orphan_check_impl(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); let trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip();
trait_ref.error_reported()?; trait_ref.error_reported()?;
match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) { match orphan_check(tcx, impl_def_id, OrphanCheckMode::Proper) {
@@ -301,13 +302,13 @@ fn orphan_check<'tcx>(
let infcx = tcx.infer_ctxt().build(TypingMode::Coherence); let infcx = tcx.infer_ctxt().build(TypingMode::Coherence);
let cause = traits::ObligationCause::dummy(); let cause = traits::ObligationCause::dummy();
let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id()); let args = infcx.fresh_args_for_item(cause.span, impl_def_id.to_def_id());
let trait_ref = trait_ref.instantiate(tcx, args); let trait_ref = trait_ref.instantiate(tcx, args).skip_norm_wip();
let lazily_normalize_ty = |user_ty: Ty<'tcx>| { let lazily_normalize_ty = |user_ty: Ty<'tcx>| {
let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) }; let ty::Alias(..) = user_ty.kind() else { return Ok(user_ty) };
let ocx = traits::ObligationCtxt::new(&infcx); let ocx = traits::ObligationCtxt::new(&infcx);
let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty); let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), Unnormalized::new_wip(user_ty));
let ty = infcx.resolve_vars_if_possible(ty); let ty = infcx.resolve_vars_if_possible(ty);
let errors = ocx.try_evaluate_obligations(); let errors = ocx.try_evaluate_obligations();
if !errors.is_empty() { if !errors.is_empty() {
@@ -318,7 +319,7 @@ fn orphan_check<'tcx>(
ocx.structurally_normalize_ty( ocx.structurally_normalize_ty(
&cause, &cause,
ty::ParamEnv::empty(), ty::ParamEnv::empty(),
infcx.resolve_vars_if_possible(ty), Unnormalized::new_wip(infcx.resolve_vars_if_possible(ty)),
) )
.unwrap_or(ty) .unwrap_or(ty)
} else { } else {
@@ -18,7 +18,7 @@ pub(super) fn check_item(
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let unsafe_attr = let unsafe_attr =
tcx.generics_of(def_id).own_params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); tcx.generics_of(def_id).own_params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
let trait_ref = trait_header.trait_ref.instantiate_identity(); let trait_ref = trait_header.trait_ref.instantiate_identity().skip_norm_wip();
let is_copy = tcx.is_lang_item(trait_def.def_id, LangItem::Copy); let is_copy = tcx.is_lang_item(trait_def.def_id, LangItem::Copy);
let trait_def_safety = if is_copy { let trait_def_safety = if is_copy {
+18 -12
View File
@@ -34,7 +34,8 @@
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, fold_regions, self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized,
fold_regions,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
@@ -388,7 +389,7 @@ fn select_inherent_assoc_candidates(
let candidates = candidates let candidates = candidates
.into_iter() .into_iter()
.filter(|&InherentAssocCandidate { impl_, .. }| { .filter(|&InherentAssocCandidate { impl_, .. }| {
let impl_ty = self.tcx().type_of(impl_).instantiate_identity(); let impl_ty = self.tcx().type_of(impl_).instantiate_identity().skip_norm_wip();
// See comment on doing this operation for `self_ty` // See comment on doing this operation for `self_ty`
let impl_ty = self.tcx.expand_free_alias_tys(impl_ty); let impl_ty = self.tcx.expand_free_alias_tys(impl_ty);
@@ -1033,8 +1034,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
Ctor(data) => { Ctor(data) => {
assert_matches!(data.ctor(), Some(_)); assert_matches!(data.ctor(), Some(_));
let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id(); 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 ty = tcx.type_of(adt_def_id).instantiate_identity().skip_norm_wip();
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity()); let inputs = data
.fields()
.iter()
.map(|f| tcx.type_of(f.def_id).instantiate_identity().skip_norm_wip());
// constructors for structs with `layout_scalar_valid_range` are unsafe to call // constructors for structs with `layout_scalar_valid_range` are unsafe to call
let safety = match tcx.layout_scalar_valid_range(adt_def_id) { let safety = match tcx.layout_scalar_valid_range(adt_def_id) {
(Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe, (Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe,
@@ -1339,7 +1343,7 @@ pub fn suggest_impl_trait<'tcx>(
let item_ty = ocx.normalize( let item_ty = ocx.normalize(
&ObligationCause::dummy(), &ObligationCause::dummy(),
param_env, param_env,
Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args), Unnormalized::new(Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args)),
); );
// FIXME(compiler-errors): We may benefit from resolving regions here. // FIXME(compiler-errors): We may benefit from resolving regions here.
if ocx.try_evaluate_obligations().is_empty() if ocx.try_evaluate_obligations().is_empty()
@@ -1373,7 +1377,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
let of_trait = impl_ let of_trait = impl_
.of_trait .of_trait
.unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}"));
let selfty = tcx.type_of(def_id).instantiate_identity(); let selfty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
let is_rustc_reservation = find_attr!(tcx, def_id, RustcReservationImpl(..)); let is_rustc_reservation = find_attr!(tcx, def_id, RustcReservationImpl(..));
check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);
@@ -1597,9 +1601,10 @@ fn const_param_default<'tcx>(
let def_id = local_def_id.to_def_id(); let def_id = local_def_id.to_def_id();
let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id)); let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id));
let ct = icx let ct = icx.lowerer().lower_const_arg(
.lowerer() default_ct,
.lower_const_arg(default_ct, tcx.type_of(def_id).instantiate(tcx, identity_args)); tcx.type_of(def_id).instantiate(tcx, identity_args).skip_norm_wip(),
);
ty::EarlyBinder::bind(ct) ty::EarlyBinder::bind(ct)
} }
@@ -1713,9 +1718,10 @@ fn const_of_item<'tcx>(
}; };
let icx = ItemCtxt::new(tcx, def_id); let icx = ItemCtxt::new(tcx, def_id);
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let ct = icx let ct = icx.lowerer().lower_const_arg(
.lowerer() ct_arg,
.lower_const_arg(ct_arg, tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args)); tcx.type_of(def_id.to_def_id()).instantiate(tcx, identity_args).skip_norm_wip(),
);
if let Err(e) = icx.check_tainted_by_errors() if let Err(e) = icx.check_tainted_by_errors()
&& !ct.references_error() && !ct.references_error()
{ {
@@ -3,7 +3,7 @@
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::{find_attr, intravisit}; use rustc_hir::{find_attr, intravisit};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_span::sym; use rustc_span::sym;
pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
@@ -20,7 +20,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
continue; continue;
} }
let ty = tcx.type_of(id).instantiate_identity(); let ty = tcx.type_of(id).instantiate_identity().skip_norm_wip();
let span = tcx.def_span(id); let span = tcx.def_span(id);
tcx.dcx().emit_err(crate::errors::TypeOf { span, ty }); tcx.dcx().emit_err(crate::errors::TypeOf { span, ty });
} }
@@ -32,7 +32,12 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
let attrs = tcx.get_all_attrs(id); let attrs = tcx.get_all_attrs(id);
if find_attr!(attrs, RustcDumpPredicates) { if find_attr!(attrs, RustcDumpPredicates) {
let preds = tcx.predicates_of(id).instantiate_identity(tcx).predicates; let preds = tcx
.predicates_of(id)
.instantiate_identity(tcx)
.predicates
.into_iter()
.map(Unnormalized::skip_norm_wip);
let span = tcx.def_span(id); let span = tcx.def_span(id);
let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str()); let mut diag = tcx.dcx().struct_span_err(span, sym::rustc_dump_predicates.as_str());
@@ -47,7 +52,7 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
match tcx.def_kind(id) { match tcx.def_kind(id) {
DefKind::AssocTy => { DefKind::AssocTy => {
let bounds = tcx.item_bounds(id).instantiate_identity(); let bounds = tcx.item_bounds(id).instantiate_identity().skip_norm_wip();
let span = tcx.def_span(id); let span = tcx.def_span(id);
let mut diag = tcx.dcx().struct_span_err(span, name); let mut diag = tcx.dcx().struct_span_err(span, name);
@@ -123,14 +128,14 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
let vtable_entries = match tcx.hir_item(id).kind { let vtable_entries = match tcx.hir_item(id).kind {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => { 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();
if trait_ref.has_non_region_param() { if trait_ref.skip_normalization().has_non_region_param() {
tcx.dcx().span_err( tcx.dcx().span_err(
attr_span, attr_span,
"`rustc_dump_vtable` must be applied to non-generic impl", "`rustc_dump_vtable` must be applied to non-generic impl",
); );
continue; continue;
} }
if !tcx.is_dyn_compatible(trait_ref.def_id) { if !tcx.is_dyn_compatible(trait_ref.skip_normalization().def_id) {
tcx.dcx().span_err( tcx.dcx().span_err(
attr_span, attr_span,
"`rustc_dump_vtable` must be applied to dyn-compatible trait", "`rustc_dump_vtable` must be applied to dyn-compatible trait",
@@ -150,7 +155,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
} }
hir::ItemKind::TyAlias(..) => { hir::ItemKind::TyAlias(..) => {
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity();
if ty.has_non_region_param() { if ty.skip_normalization().has_non_region_param() {
tcx.dcx().span_err( tcx.dcx().span_err(
attr_span, attr_span,
"`rustc_dump_vtable` must be applied to non-generic type", "`rustc_dump_vtable` must be applied to non-generic type",
@@ -558,7 +558,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.tcx.opt_rpitit_info(projection_ty_def_id) self.tcx.opt_rpitit_info(projection_ty_def_id)
&& fn_def_id == self.fn_def_id && fn_def_id == self.fn_def_id
{ {
self.tcx.type_of(projection_ty_def_id).instantiate(self.tcx, args) self.tcx.type_of(projection_ty_def_id).instantiate(self.tcx, args).skip_norm_wip()
} else { } else {
ty.super_fold_with(self) ty.super_fold_with(self)
} }
@@ -92,8 +92,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// parent predicates would hold, and also so that the param-env // parent predicates would hold, and also so that the param-env
// inherits these predicates as assumptions. // inherits these predicates as assumptions.
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
predicates predicates.extend(
.extend(tcx.explicit_predicates_of(fn_def_id).instantiate_own(tcx, identity_args)); tcx.explicit_predicates_of(fn_def_id)
.instantiate_own(tcx, identity_args)
.map(|(c, s)| (c.skip_norm_wip(), s)),
);
// We also install bidirectional outlives predicates for the RPITIT // We also install bidirectional outlives predicates for the RPITIT
// to keep the duplicates lifetimes from opaque lowering in sync. // to keep the duplicates lifetimes from opaque lowering in sync.
@@ -118,12 +121,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let impl_def_id = tcx.parent(fn_def_id); let impl_def_id = tcx.parent(fn_def_id);
let impl_trait_ref_args = tcx.impl_trait_ref(impl_def_id).instantiate_identity().args; let impl_trait_ref_args =
tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip().args;
let impl_assoc_args = let impl_assoc_args =
impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args); impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args);
let impl_predicates = trait_assoc_predicates.instantiate_own(tcx, impl_assoc_args); let impl_predicates = trait_assoc_predicates
.instantiate_own(tcx, impl_assoc_args)
.map(|(c, s)| (c.skip_norm_wip(), s));
return ty::GenericPredicates { return ty::GenericPredicates {
parent: Some(impl_def_id), parent: Some(impl_def_id),
@@ -161,8 +167,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
if let Some(of_trait) = impl_.of_trait if let Some(of_trait) = impl_.of_trait
&& of_trait.defaultness.is_default() && of_trait.defaultness.is_default()
{ {
is_default_impl_trait = is_default_impl_trait = Some(ty::Binder::dummy(
Some(ty::Binder::dummy(tcx.impl_trait_ref(def_id).instantiate_identity())); tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip(),
));
} }
} }
ItemKind::Trait(_, _, _, _, _, _, self_bounds, ..) ItemKind::Trait(_, _, _, _, _, _, self_bounds, ..)
@@ -248,7 +255,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
} }
hir::GenericParamKind::Const { .. } => { hir::GenericParamKind::Const { .. } => {
let param_def_id = param.def_id.to_def_id(); let param_def_id = param.def_id.to_def_id();
let ct_ty = tcx.type_of(param_def_id).instantiate_identity(); let ct_ty = tcx.type_of(param_def_id).instantiate_identity().skip_norm_wip();
let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id); let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id);
predicates predicates
.insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span)); .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
@@ -345,9 +352,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// in trait checking. See `setup_constraining_predicates` // in trait checking. See `setup_constraining_predicates`
// for details. // for details.
if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node { if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node {
let self_ty = tcx.type_of(def_id).instantiate_identity(); let self_ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
let trait_ref = let trait_ref = impl_
impl_.of_trait.is_some().then(|| tcx.impl_trait_ref(def_id).instantiate_identity()); .of_trait
.is_some()
.then(|| tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip());
cgp::setup_constraining_predicates( cgp::setup_constraining_predicates(
tcx, tcx,
&mut predicates, &mut predicates,
@@ -465,18 +474,18 @@ fn visit_const(&mut self, c: ty::Const<'tcx>) {
if impl_.of_trait.is_some() { if impl_.of_trait.is_some() {
debug!("visit impl trait_ref"); debug!("visit impl trait_ref");
let trait_ref = tcx.impl_trait_ref(def_id); let trait_ref = tcx.impl_trait_ref(def_id);
trait_ref.instantiate_identity().visit_with(&mut collector); trait_ref.instantiate_identity().skip_norm_wip().visit_with(&mut collector);
} }
debug!("visit self_ty"); debug!("visit self_ty");
let self_ty = tcx.type_of(def_id); let self_ty = tcx.type_of(def_id);
self_ty.instantiate_identity().visit_with(&mut collector); self_ty.instantiate_identity().skip_norm_wip().visit_with(&mut collector);
} }
if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) { if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) {
debug!("visit fn sig"); debug!("visit fn sig");
let fn_sig = tcx.fn_sig(def_id); let fn_sig = tcx.fn_sig(def_id);
let fn_sig = fn_sig.instantiate_identity(); let fn_sig = fn_sig.instantiate_identity().skip_norm_wip();
debug!(?fn_sig); debug!(?fn_sig);
fn_sig.visit_with(&mut collector); fn_sig.visit_with(&mut collector);
} }
@@ -23,7 +23,7 @@
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::middle::resolve_bound_vars::*;
use rustc_middle::query::Providers; 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_middle::{bug, span_bug};
use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::{Ident, Span, sym}; use rustc_span::{Ident, Span, sym};
@@ -1883,7 +1883,11 @@ fn visit_segment_args(
.map(|param| generic_param_def_as_bound_arg(param)), .map(|param| generic_param_def_as_bound_arg(param)),
); );
bound_vars.extend( bound_vars.extend(
self.tcx.fn_sig(assoc_fn.def_id).instantiate_identity().bound_vars(), self.tcx
.fn_sig(assoc_fn.def_id)
.instantiate_identity()
.skip_norm_wip()
.bound_vars(),
); );
bound_vars bound_vars
} else { } else {
@@ -1967,21 +1971,24 @@ fn supertrait_hrtb_vars(
break Some((bound_vars.into_iter().collect(), assoc_item)); break Some((bound_vars.into_iter().collect(), assoc_item));
} }
let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_ident)); let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_ident));
let obligations = predicates.iter_identity_copied().filter_map(|(pred, _)| { let obligations = predicates
let bound_predicate = pred.kind(); .iter_identity_copied()
match bound_predicate.skip_binder() { .map(Unnormalized::skip_norm_wip)
ty::ClauseKind::Trait(data) => { .filter_map(|(pred, _)| {
// The order here needs to match what we would get from let bound_predicate = pred.kind();
// `rustc_middle::ty::predicate::Clause::instantiate_supertrait` match bound_predicate.skip_binder() {
let pred_bound_vars = bound_predicate.bound_vars(); ty::ClauseKind::Trait(data) => {
let mut all_bound_vars = bound_vars.clone(); // The order here needs to match what we would get from
all_bound_vars.extend(pred_bound_vars.iter()); // `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
let super_def_id = data.trait_ref.def_id; let pred_bound_vars = bound_predicate.bound_vars();
Some((super_def_id, all_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)); let obligations = obligations.filter(|o| visited.insert(o.0));
stack.extend(obligations); stack.extend(obligations);
@@ -2197,7 +2204,9 @@ fn try_append_return_type_notation_params(
.iter() .iter()
.map(|param| generic_param_def_as_bound_arg(param)), .map(|param| generic_param_def_as_bound_arg(param)),
); );
bound_vars.extend(self.tcx.fn_sig(item_def_id).instantiate_identity().bound_vars()); bound_vars.extend(
self.tcx.fn_sig(item_def_id).instantiate_identity().skip_norm_wip().bound_vars(),
);
// SUBTLE: Stash the old bound vars onto the *item segment* before appending // 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 // the new bound vars. We do this because we need to know how many bound vars
@@ -2453,7 +2462,9 @@ fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
arg_is_constrained: vec![false; generics.own_params.len()] arg_is_constrained: vec![false; generics.own_params.len()]
.into_boxed_slice(), .into_boxed_slice(),
}; };
walker.visit_ty(self.tcx.type_of(*alias_def).instantiate_identity()); walker.visit_ty(
self.tcx.type_of(*alias_def).instantiate_identity().skip_norm_wip(),
);
match segments.last() { match segments.last() {
Some(hir::PathSegment { args: Some(args), .. }) => { Some(hir::PathSegment { args: Some(args), .. }) => {
@@ -182,7 +182,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
} }
}, },
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity(), Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity().skip_norm_wip(),
Node::ForeignItem(foreign_item) => match foreign_item.kind { Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => { ForeignItemKind::Fn(..) => {
@@ -205,7 +205,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
VariantData::Unit(..) | VariantData::Struct { .. } => { VariantData::Unit(..) | VariantData::Struct { .. } => {
tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity() tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity().skip_norm_wip()
} }
VariantData::Tuple(_, _, ctor) => { VariantData::Tuple(_, _, ctor) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id); let args = ty::GenericArgs::identity_for_item(tcx, def_id);
@@ -356,7 +356,7 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx
Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. }) Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
if c.hir_id == hir_id => if c.hir_id == hir_id =>
{ {
tcx.type_of(field_def_id).instantiate_identity() tcx.type_of(field_def_id).instantiate_identity().skip_norm_wip()
} }
_ => Ty::new_error_with_message( _ => Ty::new_error_with_message(
@@ -418,7 +418,7 @@ fn infer_placeholder_type<'tcx>(
// which `type const`s don't. // which `type const`s don't.
let ty = if tcx.is_type_const(def_id.to_def_id()) { 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()) { if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) {
tcx.type_of(trait_item_def_id).instantiate_identity() tcx.type_of(trait_item_def_id).instantiate_identity().skip_norm_wip()
} else { } else {
Ty::new_error_with_message( Ty::new_error_with_message(
tcx, tcx,
+11 -6
View File
@@ -281,9 +281,9 @@ fn get_delegation_self_ty<'tcx>(tcx: TyCtxt<'tcx>, delegation_id: LocalDefId) ->
} }
(FnKind::AssocTraitImpl, FnKind::AssocTrait) (FnKind::AssocTraitImpl, FnKind::AssocTrait)
| (FnKind::AssocInherentImpl, FnKind::AssocTrait) => { | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => Some(
Some(tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity()) tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip(),
} ),
// For trait impl's `sig_id` is always equal to the corresponding trait method. // For trait impl's `sig_id` is always equal to the corresponding trait method.
// For inherent methods delegation is not yet supported. // For inherent methods delegation is not yet supported.
@@ -339,7 +339,8 @@ fn create_generic_args<'tcx>(
// them as parent args. We always generate a function whose generics match // them as parent args. We always generate a function whose generics match
// child generics in trait. // child generics in trait.
let parent = tcx.local_parent(delegation_id); let parent = tcx.local_parent(delegation_id);
parent_args = tcx.impl_trait_header(parent).trait_ref.instantiate_identity().args; parent_args =
tcx.impl_trait_header(parent).trait_ref.instantiate_identity().skip_norm_wip().args;
assert!(child_args.is_empty(), "Child args can not be used in trait impl case"); assert!(child_args.is_empty(), "Child args can not be used in trait impl case");
@@ -347,7 +348,8 @@ fn create_generic_args<'tcx>(
} }
(FnKind::AssocInherentImpl, FnKind::AssocTrait) => { (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
let self_ty = tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity(); let self_ty =
tcx.type_of(tcx.local_parent(delegation_id)).instantiate_identity().skip_norm_wip();
tcx.mk_args_from_iter( tcx.mk_args_from_iter(
std::iter::once(ty::GenericArg::from(self_ty)) std::iter::once(ty::GenericArg::from(self_ty))
@@ -457,7 +459,10 @@ fn with_own_preds(
for pred in preds.predicates { for pred in preds.predicates {
let new_pred = pred.0.fold_with(&mut self.folder); let new_pred = pred.0.fold_with(&mut self.folder);
self.preds.push((EarlyBinder::bind(new_pred).instantiate(self.tcx, args), pred.1)); self.preds.push((
EarlyBinder::bind(new_pred).instantiate(self.tcx, args).skip_norm_wip(),
pred.1,
));
} }
self self
@@ -543,7 +543,7 @@ pub(super) fn lower_assoc_item_constraint(
hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Ty(ty) => self.lower_ty(ty).into(),
hir::Term::Const(ct) => { hir::Term::Const(ct) => {
let ty = projection_term.map_bound(|alias| { let ty = projection_term.map_bound(|alias| {
tcx.type_of(alias.def_id).instantiate(tcx, alias.args) tcx.type_of(alias.def_id).instantiate(tcx, alias.args).skip_norm_wip()
}); });
let ty = check_assoc_const_binding_type( let ty = check_assoc_const_binding_type(
self, self,
@@ -851,7 +851,7 @@ fn lower_return_type_notation_ty(
// `rustc_middle::ty::predicate::Clause::instantiate_supertrait` // `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
// and it's no coincidence why. // and it's no coincidence why.
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args)) Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args).skip_norm_wip())
} }
} }
@@ -436,7 +436,7 @@ pub(crate) fn report_missing_self_ty_for_resolved_path(
tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx) tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
&& header.polarity != ty::ImplPolarity::Negative && header.polarity != ty::ImplPolarity::Negative
}) })
.map(|header| header.trait_ref.instantiate_identity().self_ty()) .map(|header| header.trait_ref.instantiate_identity().skip_norm_wip().self_ty())
// We don't care about blanket impls. // We don't care about blanket impls.
.filter(|self_ty| !self_ty.has_non_region_param()) .filter(|self_ty| !self_ty.has_non_region_param())
.map(|self_ty| tcx.erase_and_anonymize_regions(self_ty).to_string()) .map(|self_ty| tcx.erase_and_anonymize_regions(self_ty).to_string())
@@ -511,7 +511,7 @@ pub(super) fn report_unresolved_type_relative_path(
} }
Some((hir::def::CtorKind::Fn, def_id)) => { Some((hir::def::CtorKind::Fn, def_id)) => {
// tuple // tuple
let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let inputs = fn_sig.inputs().skip_binder(); let inputs = fn_sig.inputs().skip_binder();
suggestion = vec![( suggestion = vec![(
ident.span.with_hi(expr.span.hi()), ident.span.with_hi(expr.span.hi()),
@@ -728,7 +728,7 @@ fn note_ambiguous_inherent_assoc_item(
"the candidate".into() "the candidate".into()
}; };
let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity(); let impl_ty = tcx.at(span).type_of(impl_).instantiate_identity().skip_norm_wip();
let note = format!("{title} is defined in an impl for the type `{impl_ty}`"); let note = format!("{title} is defined in an impl for the type `{impl_ty}`");
if let Some(span) = note_span { if let Some(span) = note_span {
@@ -782,7 +782,10 @@ pub(crate) fn report_unresolved_inherent_assoc_item(
.iter() .iter()
.take(limit) .take(limit)
.map(|cand| { .map(|cand| {
format!("- `{}`", tcx.at(span).type_of(cand.impl_).instantiate_identity()) format!(
"- `{}`",
tcx.at(span).type_of(cand.impl_).instantiate_identity().skip_norm_wip()
)
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join("\n");
@@ -1786,7 +1789,7 @@ fn generics_args_err_extend<'a>(
); );
} }
GenericsArgsErrExtend::SelfTyAlias { def_id, span } => { GenericsArgsErrExtend::SelfTyAlias { def_id, span } => {
let ty = tcx.at(span).type_of(def_id).instantiate_identity(); let ty = tcx.at(span).type_of(def_id).instantiate_identity().skip_norm_wip();
let span_of_impl = tcx.span_of_impl(def_id); let span_of_impl = tcx.span_of_impl(def_id);
let ty::Adt(self_def, _) = *ty.kind() else { return }; let ty::Adt(self_def, _) = *ty.kind() else { return };
let def_id = self_def.did(); let def_id = self_def.did();
@@ -75,7 +75,8 @@ fn generic_arg_mismatch_err(
Res::Def(DefKind::TyParam, src_def_id) => { Res::Def(DefKind::TyParam, src_def_id) => {
if let Some(param_local_id) = param.def_id.as_local() { if let Some(param_local_id) = param.def_id.as_local() {
let param_name = tcx.hir_ty_param_name(param_local_id); let param_name = tcx.hir_ty_param_name(param_local_id);
let param_type = tcx.type_of(param.def_id).instantiate_identity(); let param_type =
tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip();
if param_type.is_suggestable(tcx, false) { if param_type.is_suggestable(tcx, false) {
err.span_suggestion_verbose( err.span_suggestion_verbose(
tcx.def_span(src_def_id), tcx.def_span(src_def_id),
@@ -39,8 +39,8 @@
use rustc_middle::ty::print::PrintPolyTraitRefExt as _; use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput,
Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, const_lit_matches_ty, Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast,
fold_regions, const_lit_matches_ty, fold_regions,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -783,7 +783,9 @@ fn provided_kind(
// Ambig portions of `ConstArg` are handled in the match arm below // Ambig portions of `ConstArg` are handled in the match arm below
.lower_const_arg( .lower_const_arg(
ct.as_unambig_ct(), ct.as_unambig_ct(),
tcx.type_of(param.def_id).instantiate(tcx, preceding_args), tcx.type_of(param.def_id)
.instantiate(tcx, preceding_args)
.skip_norm_wip(),
) )
.into(), .into(),
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
@@ -828,6 +830,7 @@ fn inferred_kind(
tcx.at(self.span) tcx.at(self.span)
.type_of(param.def_id) .type_of(param.def_id)
.instantiate(tcx, preceding_args) .instantiate(tcx, preceding_args)
.skip_norm_wip()
.into() .into()
} else if synthetic { } else if synthetic {
Ty::new_param(tcx, param.index, param.name).into() Ty::new_param(tcx, param.index, param.name).into()
@@ -842,13 +845,15 @@ fn inferred_kind(
let ty = tcx let ty = tcx
.at(self.span) .at(self.span)
.type_of(param.def_id) .type_of(param.def_id)
.instantiate(tcx, preceding_args); .instantiate(tcx, preceding_args)
.skip_norm_wip();
if let Err(guar) = ty.error_reported() { if let Err(guar) = ty.error_reported() {
return ty::Const::new_error(tcx, guar).into(); return ty::Const::new_error(tcx, guar).into();
} }
if !infer_args && has_default { if !infer_args && has_default {
tcx.const_param_default(param.def_id) tcx.const_param_default(param.def_id)
.instantiate(tcx, preceding_args) .instantiate(tcx, preceding_args)
.skip_norm_wip()
.into() .into()
} else if infer_args { } else if infer_args {
self.lowerer.ct_infer(Some(param), self.span).into() self.lowerer.ct_infer(Some(param), self.span).into()
@@ -1217,7 +1222,7 @@ fn lower_path_segment(
let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id }, args); let alias_ty = ty::AliasTy::new_from_args(tcx, ty::Free { def_id }, args);
Ty::new_alias(tcx, alias_ty) Ty::new_alias(tcx, alias_ty)
} else { } else {
tcx.at(span).type_of(def_id).instantiate(tcx, args) tcx.at(span).type_of(def_id).instantiate(tcx, args).skip_norm_wip()
} }
} }
@@ -1247,6 +1252,7 @@ fn probe_single_ty_param_bound_for_assoc_item(
|| { || {
let trait_refs = predicates let trait_refs = predicates
.iter_identity_copied() .iter_identity_copied()
.map(Unnormalized::skip_norm_wip)
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))); .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) traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
}, },
@@ -1368,7 +1374,9 @@ fn probe_single_bound_for_assoc_item<I>(
// FIXME(mgca): code duplication with other places we lower // FIXME(mgca): code duplication with other places we lower
// the rhs' of associated const bindings // the rhs' of associated const bindings
let ty = projection_term.map_bound(|alias| { let ty = projection_term.map_bound(|alias| {
tcx.type_of(alias.def_id).instantiate(tcx, alias.args) tcx.type_of(alias.def_id)
.instantiate(tcx, alias.args)
.skip_norm_wip()
}); });
let ty = bounds::check_assoc_const_binding_type( let ty = bounds::check_assoc_const_binding_type(
self, self,
@@ -1712,7 +1720,8 @@ fn resolve_type_relative_path(
self.probe_single_bound_for_assoc_item( self.probe_single_bound_for_assoc_item(
|| { || {
let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity()); let trait_ref =
ty::Binder::dummy(trait_ref.instantiate_identity().skip_norm_wip());
traits::supertraits(tcx, trait_ref) traits::supertraits(tcx, trait_ref)
}, },
AssocItemQSelf::SelfTyAlias, AssocItemQSelf::SelfTyAlias,
@@ -1945,10 +1954,7 @@ fn probe_traits_that_match_assoc_ty(
&& tcx.all_impls(*trait_def_id) && tcx.all_impls(*trait_def_id)
.any(|impl_def_id| { .any(|impl_def_id| {
let header = tcx.impl_trait_header(impl_def_id); let header = tcx.impl_trait_header(impl_def_id);
let trait_ref = header.trait_ref.instantiate( let trait_ref = header.trait_ref.instantiate(tcx, infcx.fresh_args_for_item(DUMMY_SP, impl_def_id)).skip_norm_wip();
tcx,
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
);
let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased); let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
// FIXME: Don't bother dealing with non-lifetime binders here... // FIXME: Don't bother dealing with non-lifetime binders here...
@@ -2307,7 +2313,7 @@ pub fn lower_resolved_ty_path(
// `Self` in impl (we know the concrete type). // `Self` in impl (we know the concrete type).
assert_eq!(opt_self_ty, None); assert_eq!(opt_self_ty, None);
// Try to evaluate any array length constants. // Try to evaluate any array length constants.
let ty = tcx.at(span).type_of(def_id).instantiate_identity(); let ty = tcx.at(span).type_of(def_id).instantiate_identity().skip_norm_wip();
let _ = self.prohibit_generic_args( let _ = self.prohibit_generic_args(
path.segments.iter(), path.segments.iter(),
GenericsArgsErrExtend::SelfTyAlias { def_id, span }, GenericsArgsErrExtend::SelfTyAlias { def_id, span },
@@ -2616,7 +2622,10 @@ fn lower_const_arg_tuple_call(
.iter() .iter()
.zip(args) .zip(args)
.map(|(field_def, arg)| { .map(|(field_def, arg)| {
self.lower_const_arg(arg, tcx.type_of(field_def.did).instantiate(tcx, adt_args)) self.lower_const_arg(
arg,
tcx.type_of(field_def.did).instantiate(tcx, adt_args).skip_norm_wip(),
)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -2737,7 +2746,7 @@ fn lower_const_arg_struct(
self.lower_const_arg( self.lower_const_arg(
expr.expr, expr.expr,
tcx.type_of(field_def.did).instantiate(tcx, adt_args), tcx.type_of(field_def.did).instantiate(tcx, adt_args).skip_norm_wip(),
) )
} }
None => { None => {
@@ -2946,7 +2955,7 @@ fn lower_const_arg_anon(&self, anon: &AnonConst) -> Const<'tcx> {
// FIXME(generic_const_parameter_types): We should use the proper generic args // 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 // 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. // generic arguments, just weaker type inference.
let ty = tcx.type_of(anon.def_id).instantiate_identity(); let ty = tcx.type_of(anon.def_id).instantiate_identity().skip_norm_wip();
match self.try_lower_anon_const_lit(ty, expr) { match self.try_lower_anon_const_lit(ty, expr) {
Some(v) => v, Some(v) => v,
@@ -3057,7 +3066,7 @@ fn require_type_const_attribute(
fn lower_delegation_ty(&self, infer: hir::InferDelegation<'tcx>) -> Ty<'tcx> { fn lower_delegation_ty(&self, infer: hir::InferDelegation<'tcx>) -> Ty<'tcx> {
match infer { match infer {
hir::InferDelegation::DefId(def_id) => { hir::InferDelegation::DefId(def_id) => {
self.tcx().type_of(def_id).instantiate_identity() self.tcx().type_of(def_id).instantiate_identity().skip_norm_wip()
} }
rustc_hir::InferDelegation::Sig(_, idx) => { rustc_hir::InferDelegation::Sig(_, idx) => {
let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
@@ -3648,10 +3657,15 @@ pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
trait_ref.def_id, trait_ref.def_id,
)?; )?;
let fn_sig = tcx.fn_sig(assoc.def_id).instantiate( let fn_sig = tcx
tcx, .fn_sig(assoc.def_id)
trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)), .instantiate(
); tcx,
trait_ref
.args
.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
)
.skip_norm_wip();
let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig); 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 { Some(if let Some(arg_idx) = arg_idx {
@@ -16,7 +16,7 @@
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId; 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 rustc_span::{ErrorGuaranteed, kw};
use crate::constrained_generic_params as cgp; use crate::constrained_generic_params as cgp;
@@ -78,7 +78,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
of_trait: bool, of_trait: bool,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip();
// Don't complain about unconstrained type params when self ty isn't known due to errors. // Don't complain about unconstrained type params when self ty isn't known due to errors.
// (#36836) // (#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_generics = tcx.generics_of(impl_def_id);
let impl_predicates = tcx.predicates_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id);
let impl_trait_ref = of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate_identity()); let impl_trait_ref =
of_trait.then(|| tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip());
impl_trait_ref.error_reported()?; impl_trait_ref.error_reported()?;
@@ -107,7 +108,11 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
match item.kind { match item.kind {
ty::AssocKind::Type { .. } => { ty::AssocKind::Type { .. } => {
if item.defaultness(tcx).has_value() { if item.defaultness(tcx).has_value() {
cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true) cgp::parameters_for(
tcx,
tcx.type_of(def_id).instantiate_identity().skip_norm_wip(),
true,
)
} else { } else {
vec![] vec![]
} }
@@ -187,7 +192,7 @@ pub(crate) fn enforce_impl_non_lifetime_params_are_constrained(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
impl_def_id: LocalDefId, impl_def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip();
// Don't complain about unconstrained type params when self ty isn't known due to errors. // Don't complain about unconstrained type params when self ty isn't known due to errors.
// (#36836) // (#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_generics = tcx.generics_of(impl_def_id);
let impl_predicates = tcx.predicates_of(impl_def_id); let impl_predicates = tcx.predicates_of(impl_def_id);
let impl_trait_ref = let impl_trait_ref = tcx
tcx.impl_opt_trait_ref(impl_def_id).map(ty::EarlyBinder::instantiate_identity); .impl_opt_trait_ref(impl_def_id)
.map(ty::EarlyBinder::instantiate_identity)
.map(Unnormalized::skip_norm_wip);
impl_trait_ref.error_reported()?; impl_trait_ref.error_reported()?;
@@ -215,7 +215,7 @@ fn unconstrained_parent_impl_args<'tcx>(
let impl_generic_predicates = tcx.predicates_of(impl_def_id); let impl_generic_predicates = tcx.predicates_of(impl_def_id);
let mut unconstrained_parameters = FxHashSet::default(); let mut unconstrained_parameters = FxHashSet::default();
let mut constrained_params = FxHashSet::default(); let mut constrained_params = FxHashSet::default();
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip();
// Unfortunately the functions in `constrained_generic_parameters` don't do // Unfortunately the functions in `constrained_generic_parameters` don't do
// what we want here. We want only a list of constrained parameters while // what we want here. We want only a list of constrained parameters while
@@ -326,7 +326,10 @@ fn check_predicates<'tcx>(
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl1_predicates: Vec<_> = traits::elaborate( let impl1_predicates: Vec<_> = traits::elaborate(
tcx, tcx,
tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_args).into_iter(), tcx.predicates_of(impl1_def_id)
.instantiate(tcx, impl1_args)
.into_iter()
.map(|(c, s)| (c.skip_norm_wip(), s)),
) )
.collect(); .collect();
@@ -340,7 +343,7 @@ fn check_predicates<'tcx>(
tcx.predicates_of(impl2_node.def_id()) tcx.predicates_of(impl2_node.def_id())
.instantiate(tcx, impl2_args) .instantiate(tcx, impl2_args)
.into_iter() .into_iter()
.map(|(c, _s)| c.as_predicate()), .map(|(c, _s)| c.skip_norm_wip().as_predicate()),
) )
.collect() .collect()
}; };
@@ -373,7 +376,7 @@ fn check_predicates<'tcx>(
.map(|(c, _span)| c.as_predicate()); .map(|(c, _span)| c.as_predicate());
// Include the well-formed predicates of the type parameters of the impl. // Include the well-formed predicates of the type parameters of the impl.
for arg in tcx.impl_trait_ref(impl1_def_id).instantiate_identity().args { for arg in tcx.impl_trait_ref(impl1_def_id).instantiate_identity().skip_norm_wip().args {
let Some(term) = arg.as_term() else { let Some(term) = arg.as_term() else {
continue; continue;
}; };
@@ -46,7 +46,8 @@ pub(super) fn infer_predicates(
// For field of type &'a T (reference) or Adt // For field of type &'a T (reference) or Adt
// (struct/enum/union) there will be outlive // (struct/enum/union) there will be outlive
// requirements for adt_def. // requirements for adt_def.
let field_ty = tcx.type_of(field_def.did).instantiate_identity(); let field_ty =
tcx.type_of(field_def.did).instantiate_identity().skip_norm_wip();
let field_span = tcx.def_span(field_def.did); let field_span = tcx.def_span(field_def.did);
insert_required_predicates_to_be_wf( insert_required_predicates_to_be_wf(
tcx, tcx,
@@ -62,7 +63,7 @@ pub(super) fn infer_predicates(
DefKind::TyAlias if tcx.type_alias_is_lazy(item_did) => { DefKind::TyAlias if tcx.type_alias_is_lazy(item_did) => {
insert_required_predicates_to_be_wf( insert_required_predicates_to_be_wf(
tcx, tcx,
tcx.type_of(item_did).instantiate_identity(), tcx.type_of(item_did).instantiate_identity().skip_norm_wip(),
tcx.def_span(item_did), tcx.def_span(item_did),
&global_inferred_outlives, &global_inferred_outlives,
&mut item_required_predicates, &mut item_required_predicates,
@@ -306,7 +307,8 @@ fn check_explicit_predicates<'tcx>(
continue; continue;
} }
let predicate = explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args); let predicate =
explicit_predicates.rebind(*outlives_predicate).instantiate(tcx, args).skip_norm_wip();
debug!("predicate = {predicate:?}"); debug!("predicate = {predicate:?}");
insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates); insert_outlives_predicate(tcx, predicate.0, predicate.1, span, required_predicates);
} }
@@ -349,7 +351,7 @@ fn check_inferred_predicates<'tcx>(
// `predicate` is `U: 'b` in the example above. // `predicate` is `U: 'b` in the example above.
// So apply the instantiation to get `T: 'a`. // So apply the instantiation to get `T: 'a`.
let ty::OutlivesPredicate(arg, region) = let ty::OutlivesPredicate(arg, region) =
predicates.rebind(predicate).instantiate(tcx, args); predicates.rebind(predicate).instantiate(tcx, args).skip_norm_wip();
insert_outlives_predicate(tcx, arg, region, span, required_predicates); insert_outlives_predicate(tcx, arg, region, span, required_predicates);
} }
} }
@@ -105,7 +105,7 @@ fn build_constraints_for_item(&mut self, def_id: LocalDefId) {
let inferred_start = self.terms_cx.inferred_starts[&def_id]; let inferred_start = self.terms_cx.inferred_starts[&def_id];
let current_item = &CurrentItem { inferred_start }; let current_item = &CurrentItem { inferred_start };
let ty = tcx.type_of(def_id).instantiate_identity(); let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
// The type as returned by `type_of` is the underlying type and generally not a free alias. // 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. // Therefore we need to check the `DefKind` first.
@@ -127,7 +127,7 @@ fn build_constraints_for_item(&mut self, def_id: LocalDefId) {
for field in def.all_fields() { for field in def.all_fields() {
self.add_constraints_from_ty( self.add_constraints_from_ty(
current_item, current_item,
tcx.type_of(field.did).instantiate_identity(), tcx.type_of(field.did).instantiate_identity().skip_norm_wip(),
self.covariant, self.covariant,
); );
} }
@@ -136,7 +136,7 @@ fn build_constraints_for_item(&mut self, def_id: LocalDefId) {
ty::FnDef(..) => { ty::FnDef(..) => {
self.add_constraints_from_sig( self.add_constraints_from_sig(
current_item, current_item,
tcx.fn_sig(def_id).instantiate_identity(), tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(),
self.covariant, self.covariant,
); );
} }
@@ -11,6 +11,7 @@
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
Unnormalized,
}; };
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@@ -185,7 +186,11 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
let mut collector = let mut collector =
OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances };
let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id); let id_args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
for (pred, _) in tcx.explicit_item_bounds(item_def_id).iter_instantiated_copied(tcx, id_args) { for (pred, _) in tcx
.explicit_item_bounds(item_def_id)
.iter_instantiated_copied(tcx, id_args)
.map(Unnormalized::skip_norm_wip)
{
debug!(?pred); debug!(?pred);
// We only ignore opaque type args if the opaque type is the outermost type. // We only ignore opaque type args if the opaque type is the outermost type.
@@ -122,7 +122,9 @@ fn create_map(&self) -> DefIdMap<&'tcx [ty::Variance]> {
self.enforce_const_invariance(generics, variances); self.enforce_const_invariance(generics, variances);
// Functions are permitted to have unused generic parameters: make those invariant. // Functions are permitted to have unused generic parameters: make those invariant.
if let ty::FnDef(..) = tcx.type_of(def_id).instantiate_identity().kind() { if let ty::FnDef(..) =
tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind()
{
for variance in variances.iter_mut() { for variance in variances.iter_mut() {
if *variance == ty::Bivariant { if *variance == ty::Bivariant {
*variance = ty::Invariant; *variance = ty::Invariant;
+5 -4
View File
@@ -12,7 +12,7 @@
use rustc_middle::ty::adjustment::{ use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
}; };
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::{Span, sym}; use rustc_span::{Span, sym};
@@ -540,7 +540,7 @@ fn confirm_builtin_call(
let (fn_sig, def_id) = match *callee_ty.kind() { let (fn_sig, def_id) = match *callee_ty.kind() {
ty::FnDef(def_id, args) => { ty::FnDef(def_id, args) => {
self.enforce_context_effects(Some(call_expr.hir_id), call_expr.span, def_id, args); self.enforce_context_effects(Some(call_expr.hir_id), call_expr.span, def_id, args);
let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args); let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip();
// Unit testing: function items annotated with // Unit testing: function items annotated with
// `#[rustc_evaluate_where_clauses]` trigger special output // `#[rustc_evaluate_where_clauses]` trigger special output
@@ -549,6 +549,7 @@ fn confirm_builtin_call(
let predicates = self.tcx.predicates_of(def_id); let predicates = self.tcx.predicates_of(def_id);
let predicates = predicates.instantiate(self.tcx, args); let predicates = predicates.instantiate(self.tcx, args);
for (predicate, predicate_span) in predicates { for (predicate, predicate_span) in predicates {
let predicate = predicate.skip_norm_wip();
let obligation = Obligation::new( let obligation = Obligation::new(
self.tcx, self.tcx,
ObligationCause::dummy_with_span(callee_expr.span), ObligationCause::dummy_with_span(callee_expr.span),
@@ -584,7 +585,7 @@ fn confirm_builtin_call(
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
fn_sig, fn_sig,
); );
let fn_sig = self.normalize(call_expr.span, fn_sig); let fn_sig = self.normalize(call_expr.span, Unnormalized::new_wip(fn_sig));
self.check_argument_types( self.check_argument_types(
call_expr.span, call_expr.span,
@@ -959,7 +960,7 @@ pub(super) fn enforce_context_effects(
self.tcx, self.tcx,
cause, cause,
self.param_env, self.param_env,
cond.to_host_effect_clause(self.tcx, host), cond.to_host_effect_clause(self.tcx, host).skip_norm_wip(),
)); ));
} }
} else { } else {
+7 -2
View File
@@ -40,7 +40,9 @@
use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef, elaborate}; use rustc_middle::ty::{
self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, Unnormalized, VariantDef, elaborate,
};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::{DUMMY_SP, Span, sym}; use rustc_span::{DUMMY_SP, Span, sym};
@@ -753,7 +755,10 @@ fn do_check(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<CastKind, CastError<'tcx>>
match *self.expr_ty.kind() { match *self.expr_ty.kind() {
ty::FnDef(..) => { ty::FnDef(..) => {
// Attempt a coercion to a fn pointer type. // Attempt a coercion to a fn pointer type.
let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx)); let f = fcx.normalize(
self.expr_span,
Unnormalized::new_wip(self.expr_ty.fn_sig(fcx.tcx)),
);
let res = fcx.coerce( let res = fcx.coerce(
self.expr, self.expr,
self.expr_ty, self.expr_ty,
+11 -8
View File
@@ -59,7 +59,7 @@ pub(super) fn check_fn<'a, 'tcx>(
let va_list_did = tcx.require_lang_item(LangItem::VaList, span); let va_list_did = tcx.require_lang_item(LangItem::VaList, span);
let region = fcx.next_region_var(RegionVariableOrigin::Misc(span)); let region = fcx.next_region_var(RegionVariableOrigin::Misc(span));
tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]) tcx.type_of(va_list_did).instantiate(tcx, &[region.into()]).skip_norm_wip()
}); });
// Add formal parameters. // Add formal parameters.
@@ -180,14 +180,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); let panic_info_did = tcx.require_lang_item(hir::LangItem::PanicInfo, span);
// build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` // build type `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
let panic_info_ty = tcx.type_of(panic_info_did).instantiate( let panic_info_ty = tcx
tcx, .type_of(panic_info_did)
&[ty::GenericArg::from(ty::Region::new_bound( .instantiate(
tcx, tcx,
ty::INNERMOST, &[ty::GenericArg::from(ty::Region::new_bound(
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon }, tcx,
))], ty::INNERMOST,
); ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BoundRegionKind::Anon },
))],
)
.skip_norm_wip();
let panic_info_ref_ty = Ty::new_imm_ref( let panic_info_ref_ty = Ty::new_imm_ref(
tcx, tcx,
ty::Region::new_bound( ty::Region::new_bound(
+9 -6
View File
@@ -14,7 +14,7 @@
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, ClosureKind, FnSigKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, self, ClosureKind, FnSigKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, TypeVisitableExt, TypeVisitor, Unnormalized,
}; };
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::{DUMMY_SP, Span}; use rustc_span::{DUMMY_SP, Span};
@@ -302,6 +302,7 @@ fn deduce_closure_signature(
self.tcx self.tcx
.explicit_item_self_bounds(def_id) .explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.map(Unnormalized::skip_norm_wip)
.map(|(c, s)| (c.as_predicate(), s)), .map(|(c, s)| (c.as_predicate(), s)),
), ),
ty::Dynamic(object_type, ..) => { ty::Dynamic(object_type, ..) => {
@@ -364,11 +365,11 @@ fn deduce_closure_signature_from_predicates(
{ {
let inferred_sig = self.normalize( let inferred_sig = self.normalize(
span, span,
self.deduce_sig_from_projection( Unnormalized::new_wip(self.deduce_sig_from_projection(
Some(span), Some(span),
closure_kind, closure_kind,
bound_predicate.rebind(proj_predicate), bound_predicate.rebind(proj_predicate),
), )),
); );
// Make sure that we didn't infer a signature that mentions itself. // Make sure that we didn't infer a signature that mentions itself.
@@ -945,7 +946,7 @@ fn supplied_sig_of_closure(
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result); self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
// Normalize only after registering in `user_provided_sigs`. // Normalize only after registering in `user_provided_sigs`.
self.normalize(self.tcx.def_span(expr_def_id), result) self.normalize(self.tcx.def_span(expr_def_id), Unnormalized::new_wip(result))
} }
/// Invoked when we are translating the coroutine that results /// Invoked when we are translating the coroutine that results
@@ -1001,6 +1002,7 @@ fn deduce_future_output_from_obligations(&self, body_def_id: LocalDefId) -> Opti
.tcx .tcx
.explicit_item_self_bounds(def_id) .explicit_item_self_bounds(def_id)
.iter_instantiated_copied(self.tcx, args) .iter_instantiated_copied(self.tcx, args)
.map(Unnormalized::skip_norm_wip)
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
ty::Error(_) => return Some(ret_ty), ty::Error(_) => return Some(ret_ty),
_ => { _ => {
@@ -1008,7 +1010,7 @@ fn deduce_future_output_from_obligations(&self, body_def_id: LocalDefId) -> Opti
} }
}; };
let output_ty = self.normalize(closure_span, output_ty); let output_ty = self.normalize(closure_span, Unnormalized::new_wip(output_ty));
// async fn that have opaque types in their return type need to redo the conversion to inference variables // async fn that have opaque types in their return type need to redo the conversion to inference variables
// as they fetch the still opaque version from the signature. // as they fetch the still opaque version from the signature.
@@ -1113,7 +1115,8 @@ fn closure_sigs(
) -> ClosureSignatures<'tcx> { ) -> ClosureSignatures<'tcx> {
let liberated_sig = let liberated_sig =
self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig); self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig);
let liberated_sig = self.normalize(self.tcx.def_span(expr_def_id), liberated_sig); let liberated_sig =
self.normalize(self.tcx.def_span(expr_def_id), Unnormalized::new_wip(liberated_sig));
ClosureSignatures { bound_sig, liberated_sig } ClosureSignatures { bound_sig, liberated_sig }
} }
} }
+32 -26
View File
@@ -54,7 +54,7 @@
PointerCoercion, PointerCoercion,
}; };
use rustc_middle::ty::error::TypeError; 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_span::{BytePos, DUMMY_SP, Span};
use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor}; use rustc_trait_selection::solve::inspect::{self, InferCtxtProofTreeExt, ProofTreeVisitor};
@@ -963,7 +963,7 @@ fn coerce_from_fn_item(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety()))?; let a_sig = self.sig_for_fn_def_coercion(a, Some(b_hdr.safety()))?;
let InferOk { value: a_sig, mut obligations } = let InferOk { value: a_sig, mut obligations } =
self.at(&self.cause, self.param_env).normalize(a_sig); self.at(&self.cause, self.param_env).normalize(Unnormalized::new_wip(a_sig));
let a = Ty::new_fn_ptr(self.tcx, a_sig); let a = Ty::new_fn_ptr(self.tcx, a_sig);
let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety())); let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety()));
@@ -1104,7 +1104,7 @@ pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool
if self.next_trait_solver() if self.next_trait_solver()
&& let ty::Alias(..) = ty.kind() && let ty::Alias(..) = ty.kind()
{ {
ocx.structurally_normalize_ty(&cause, self.param_env, ty) ocx.structurally_normalize_ty(&cause, self.param_env, Unnormalized::new_wip(ty))
} else { } else {
Ok(ty) Ok(ty)
} }
@@ -1336,7 +1336,7 @@ fn try_find_coercion_lub(
}; };
// The signature must match. // The signature must match.
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig)); let (a_sig, b_sig) = self.normalize(new.span, Unnormalized::new_wip((a_sig, b_sig)));
let sig = self let sig = self
.at(cause, self.param_env) .at(cause, self.param_env)
.lub(a_sig, b_sig) .lub(a_sig, b_sig)
@@ -1852,28 +1852,34 @@ fn suggest_boxing_tail_for_return_position_impl_trait(
fcx.probe(|_| { fcx.probe(|_| {
let ocx = ObligationCtxt::new(fcx); let ocx = ObligationCtxt::new(fcx);
ocx.register_obligations( ocx.register_obligations(
fcx.tcx.item_self_bounds(rpit_def_id).iter_identity().filter_map(|clause| { fcx.tcx
let predicate = clause .item_self_bounds(rpit_def_id)
.kind() .iter_identity()
.map_bound(|clause| match clause { .map(Unnormalized::skip_norm_wip)
ty::ClauseKind::Trait(trait_pred) => Some(ty::ClauseKind::Trait( .filter_map(|clause| {
trait_pred.with_replaced_self_ty(fcx.tcx, ty), let predicate = clause
)), .kind()
ty::ClauseKind::Projection(proj_pred) => { .map_bound(|clause| match clause {
Some(ty::ClauseKind::Projection( ty::ClauseKind::Trait(trait_pred) => {
proj_pred.with_replaced_self_ty(fcx.tcx, ty), Some(ty::ClauseKind::Trait(
)) trait_pred.with_replaced_self_ty(fcx.tcx, ty),
} ))
_ => None, }
}) ty::ClauseKind::Projection(proj_pred) => {
.transpose()?; Some(ty::ClauseKind::Projection(
Some(Obligation::new( proj_pred.with_replaced_self_ty(fcx.tcx, ty),
fcx.tcx, ))
ObligationCause::dummy(), }
fcx.param_env, _ => None,
predicate, })
)) .transpose()?;
}), Some(Obligation::new(
fcx.tcx,
ObligationCause::dummy(),
fcx.param_env,
predicate,
))
}),
); );
ocx.try_evaluate_obligations().is_empty() ocx.try_evaluate_obligations().is_empty()
}) })
+27 -13
View File
@@ -28,7 +28,7 @@
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, AdtKind, GenericArgsRef, Ty, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
@@ -594,7 +594,7 @@ pub(crate) fn check_expr_path(
self.add_required_obligations_with_code(expr.span, def_id, args, |_, _| { self.add_required_obligations_with_code(expr.span, def_id, args, |_, _| {
code.clone() code.clone()
}); });
return tcx.type_of(def_id).instantiate(tcx, args); return tcx.type_of(def_id).instantiate(tcx, args).skip_norm_wip();
} }
} }
@@ -1743,7 +1743,10 @@ fn check_expr_repeat(
let count_span = count.span; let count_span = count.span;
let count = self.try_structurally_resolve_const( let count = self.try_structurally_resolve_const(
count_span, count_span,
self.normalize(count_span, self.lower_const_arg(count, tcx.types.usize)), self.normalize(
count_span,
Unnormalized::new_wip(self.lower_const_arg(count, tcx.types.usize)),
),
); );
if let Some(count) = count.try_to_target_usize(tcx) { if let Some(count) = count.try_to_target_usize(tcx) {
@@ -2064,12 +2067,12 @@ fn check_expr_struct_fields(
ty::Adt(adt, args) if adt.is_struct() => variant ty::Adt(adt, args) if adt.is_struct() => variant
.fields .fields
.iter() .iter()
.map(|f| self.normalize(span, f.ty(self.tcx, args))) .map(|f| self.normalize(span, Unnormalized::new_wip(f.ty(self.tcx, args))))
.collect(), .collect(),
ty::Adt(adt, args) if adt.is_enum() => variant ty::Adt(adt, args) if adt.is_enum() => variant
.fields .fields
.iter() .iter()
.map(|f| self.normalize(span, f.ty(self.tcx, args))) .map(|f| self.normalize(span, Unnormalized::new_wip(f.ty(self.tcx, args))))
.collect(), .collect(),
_ => { _ => {
self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span }); self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { span });
@@ -2095,7 +2098,11 @@ fn check_expr_struct_fields(
.map(|f| { .map(|f| {
let fru_ty = self.normalize( let fru_ty = self.normalize(
expr.span, expr.span,
self.field_ty(base_expr.span, f, fresh_args), Unnormalized::new_wip(self.field_ty(
base_expr.span,
f,
fresh_args,
)),
); );
let ident = let ident =
self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id); self.tcx.adjust_ident(f.ident(self.tcx), variant.def_id);
@@ -2180,7 +2187,12 @@ fn check_expr_struct_fields(
ty::Adt(adt, args) if adt.is_struct() => variant ty::Adt(adt, args) if adt.is_struct() => variant
.fields .fields
.iter() .iter()
.map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) .map(|f| {
self.normalize(
expr.span,
Unnormalized::new_wip(f.ty(self.tcx, args)),
)
})
.collect(), .collect(),
_ => { _ => {
self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct { self.dcx().emit_err(FunctionalRecordUpdateOnNonStruct {
@@ -2480,7 +2492,8 @@ fn report_private_fields(
let fn_sig = self let fn_sig = self
.tcx .tcx
.fn_sig(item.def_id) .fn_sig(item.def_id)
.instantiate(self.tcx, self.fresh_args_for_item(span, item.def_id)); .instantiate(self.tcx, self.fresh_args_for_item(span, item.def_id))
.skip_norm_wip();
let ret_ty = self.tcx.instantiate_bound_regions_with_erased(fn_sig.output()); let ret_ty = self.tcx.instantiate_bound_regions_with_erased(fn_sig.output());
if !self.can_eq(self.param_env, ret_ty, adt_ty) { if !self.can_eq(self.param_env, ret_ty, adt_ty) {
return None; return None;
@@ -2592,7 +2605,7 @@ fn report_unknown_field(
), ),
); );
err.span_label(field.ident.span, "field does not exist"); err.span_label(field.ident.span, "field does not exist");
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity(); let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let inputs = fn_sig.inputs().skip_binder(); let inputs = fn_sig.inputs().skip_binder();
let fields = format!( let fields = format!(
"({})", "({})",
@@ -2620,7 +2633,7 @@ fn report_unknown_field(
_ => { _ => {
err.span_label(variant_ident_span, format!("`{ty}` defined here")); err.span_label(variant_ident_span, format!("`{ty}` defined here"));
err.span_label(field.ident.span, "field does not exist"); err.span_label(field.ident.span, "field does not exist");
let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity(); let fn_sig = self.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let inputs = fn_sig.inputs().skip_binder(); let inputs = fn_sig.inputs().skip_binder();
let fields = format!( let fields = format!(
"({})", "({})",
@@ -3215,7 +3228,8 @@ fn no_such_field_err(
{ {
err.span_label(field.span, "this is an associated function, not a method"); 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"); err.note("found the following associated function; to be used as method, it must have a `self` parameter");
let impl_ty = self.tcx.type_of(impl_def_id).instantiate_identity(); let impl_ty =
self.tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip();
err.span_note( err.span_note(
self.tcx.def_span(item.def_id), self.tcx.def_span(item.def_id),
format!("the candidate is defined in an impl for the type `{impl_ty}`"), format!("the candidate is defined in an impl for the type `{impl_ty}`"),
@@ -3586,11 +3600,11 @@ fn find_and_report_unsatisfied_index_impl(
let element_ty = ocx.normalize( let element_ty = ocx.normalize(
&cause, &cause,
self.param_env, self.param_env,
Ty::new_projection_from_args( Unnormalized::new(Ty::new_projection_from_args(
self.tcx, self.tcx,
index_trait_output_def_id, index_trait_output_def_id,
impl_trait_ref.args, impl_trait_ref.args,
), )),
); );
let true_errors = ocx.try_evaluate_obligations(); let true_errors = ocx.try_evaluate_obligations();
+2 -1
View File
@@ -632,7 +632,8 @@ fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
match ex.kind { match ex.kind {
hir::ExprKind::MethodCall(..) => { hir::ExprKind::MethodCall(..) => {
if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
&& let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() && let method_ty =
self.fcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
&& let sig = method_ty.fn_sig(self.fcx.tcx) && let sig = method_ty.fn_sig(self.fcx.tcx)
&& sig.safety().is_unsafe() && sig.safety().is_unsafe()
{ {
+18 -15
View File
@@ -71,7 +71,7 @@ pub(crate) fn transform_args_for_inherent_type_const(
let impl_def_id = assoc_item.container_id(tcx); let impl_def_id = assoc_item.container_id(tcx);
let generics = tcx.generics_of(def_id); let generics = tcx.generics_of(def_id);
let impl_args = &args[..generics.parent_count]; let impl_args = &args[..generics.parent_count];
let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args); let self_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args).skip_norm_wip();
// Build new args: [Self, own_args...] // Build new args: [Self, own_args...]
let own_args = &args[generics.parent_count..]; let own_args = &args[generics.parent_count..];
tcx.mk_args_from_iter( tcx.mk_args_from_iter(
@@ -474,7 +474,7 @@ pub(crate) fn require_type_has_static_alignment(&self, ty: Ty<'tcx>, span: Span)
if self.next_trait_solver() { if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty) self.try_structurally_resolve_type(span, ty)
} else { } else {
self.normalize(span, ty) self.normalize(span, Unnormalized::new_wip(ty))
} }
}, },
|| {}, || {},
@@ -647,7 +647,7 @@ pub(crate) fn field_ty(
field: &'tcx ty::FieldDef, field: &'tcx ty::FieldDef,
args: GenericArgsRef<'tcx>, args: GenericArgsRef<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
self.normalize(span, field.ty(self.tcx, args)) self.normalize(span, Unnormalized::new_wip(field.ty(self.tcx, args)))
} }
/// Drain all obligations that are stalled on coroutines defined in this body. /// Drain all obligations that are stalled on coroutines defined in this body.
@@ -1064,7 +1064,7 @@ pub(crate) fn instantiate_value_path(
if let Res::Local(hid) = res { if let Res::Local(hid) = res {
let ty = self.local_ty(span, hid); let ty = self.local_ty(span, hid);
let ty = self.normalize(span, ty); let ty = self.normalize(span, Unnormalized::new_wip(ty));
return (ty, res); return (ty, res);
} }
@@ -1131,7 +1131,7 @@ pub(crate) fn instantiate_value_path(
let ty = LoweredTy::from_raw( let ty = LoweredTy::from_raw(
self, self,
span, span,
tcx.at(span).type_of(impl_def_id).instantiate_identity(), tcx.at(span).type_of(impl_def_id).instantiate_identity().skip_norm_wip(),
); );
// Firstly, check that this SelfCtor even comes from the item we're currently // Firstly, check that this SelfCtor even comes from the item we're currently
@@ -1289,7 +1289,8 @@ fn provided_kind(
self.fcx self.fcx
.tcx .tcx
.type_of(param.def_id) .type_of(param.def_id)
.instantiate(self.fcx.tcx, preceding_args), .instantiate(self.fcx.tcx, preceding_args)
.skip_norm_wip(),
) )
.into(), .into(),
(&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
@@ -1309,7 +1310,7 @@ fn inferred_kind(
if !infer_args && let Some(default) = param.default_value(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 // 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. // the type/const arguments: We provide the default where any is missing.
return default.instantiate(tcx, preceding_args); return default.instantiate(tcx, preceding_args).skip_norm_wip();
} }
// If no type/const arguments were provided, we have to infer them. // 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., // This case also occurs as a result of some malformed input, e.g.,
@@ -1347,7 +1348,7 @@ fn inferred_kind(
self.write_user_type_annotation_from_args(hir_id, def_id, args_for_user_type, user_self_ty); self.write_user_type_annotation_from_args(hir_id, def_id, args_for_user_type, user_self_ty);
// Normalize only after registering type annotations. // Normalize only after registering type annotations.
let args = self.normalize(span, args_raw); let args = self.normalize(span, Unnormalized::new_wip(args_raw));
self.add_required_obligations_for_hir(span, def_id, args, hir_id); self.add_required_obligations_for_hir(span, def_id, args, hir_id);
@@ -1365,7 +1366,7 @@ fn inferred_kind(
// with the instantiated impl type. // with the instantiated impl type.
// This also occurs for an enum variant on a type alias. // 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));
let self_ty = self.normalize(span, self_ty); let self_ty = self.normalize(span, Unnormalized::new_wip(self_ty));
match self.at(&self.misc(span), self.param_env).eq( match self.at(&self.misc(span), self.param_env).eq(
DefineOpaqueTypes::Yes, DefineOpaqueTypes::Yes,
impl_ty, impl_ty,
@@ -1444,9 +1445,10 @@ pub(crate) fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty
// We need to use a separate variable here as otherwise the temporary for // We need to use a separate variable here as otherwise the temporary for
// `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting
// in a reentrant borrow, causing an ICE. // in a reentrant borrow, causing an ICE.
let result = self let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_ty(
.at(&self.misc(sp), self.param_env) Unnormalized::new_wip(ty),
.structurally_normalize_ty(ty, &mut **self.fulfillment_cx.borrow_mut()); &mut **self.fulfillment_cx.borrow_mut(),
);
match result { match result {
Ok(normalized_ty) => normalized_ty, Ok(normalized_ty) => normalized_ty,
Err(errors) => { Err(errors) => {
@@ -1473,9 +1475,10 @@ pub(crate) fn try_structurally_resolve_const(
// We need to use a separate variable here as otherwise the temporary for // We need to use a separate variable here as otherwise the temporary for
// `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting // `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting
// in a reentrant borrow, causing an ICE. // in a reentrant borrow, causing an ICE.
let result = self let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_const(
.at(&self.misc(sp), self.param_env) Unnormalized::new_wip(ct),
.structurally_normalize_const(ct, &mut **self.fulfillment_cx.borrow_mut()); &mut **self.fulfillment_cx.borrow_mut(),
);
match result { match result {
Ok(normalized_ct) => normalized_ct, Ok(normalized_ct) => normalized_ct,
Err(errors) => { Err(errors) => {
@@ -524,7 +524,7 @@ fn point_at_field_if_possible(
{ {
return Some(( return Some((
expr_field.expr, expr_field.expr,
self.tcx.type_of(field.did).instantiate_identity(), self.tcx.type_of(field.did).instantiate_identity().skip_norm_wip(),
)); ));
} }
} }
@@ -552,7 +552,7 @@ fn blame_specific_arg_if_possible(
receiver: Option<&'tcx hir::Expr<'tcx>>, receiver: Option<&'tcx hir::Expr<'tcx>>,
args: &'tcx [hir::Expr<'tcx>], args: &'tcx [hir::Expr<'tcx>],
) -> bool { ) -> bool {
let ty = self.tcx.type_of(def_id).instantiate_identity(); let ty = self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
if !ty.is_fn() { if !ty.is_fn() {
return false; return false;
} }
@@ -18,7 +18,7 @@
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TypeTrace}; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TypeTrace};
use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
@@ -95,8 +95,10 @@ pub(in super::super) fn check_repeat_exprs(&self) {
// as otherwise we can wind up conservatively proving `Copy` which may // as otherwise we can wind up conservatively proving `Copy` which may
// infer the repeat expr count to something that never required `Copy` in // infer the repeat expr count to something that never required `Copy` in
// the first place. // the first place.
let count = self let count = self.structurally_resolve_const(
.structurally_resolve_const(element.span, self.normalize(element.span, count)); element.span,
self.normalize(element.span, Unnormalized::new_wip(count)),
);
// Avoid run on "`NotCopy: Copy` is not implemented" errors when the // Avoid run on "`NotCopy: Copy` is not implemented" errors when the
// repeat expr count is erroneous/unknown. The user might wind up // repeat expr count is erroneous/unknown. The user might wind up
@@ -1406,7 +1408,8 @@ fn label_fn_like(
// fn-like predicates with different args, but callable types really never // fn-like predicates with different args, but callable types really never
// do that, so it's OK. // do that, so it's OK.
for (predicate, span) in instantiated { for (predicate, span) in instantiated {
if let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder() if let ty::ClauseKind::Trait(pred) =
predicate.skip_norm_wip().kind().skip_binder()
&& pred.self_ty().peel_refs() == callee_ty && pred.self_ty().peel_refs() == callee_ty
&& self.tcx.is_fn_trait(pred.def_id()) && self.tcx.is_fn_trait(pred.def_id())
{ {
@@ -3030,7 +3033,8 @@ fn similar_assoc(&self, call_name: Ident) -> Option<(ty::AssocItem, ty::FnSig<'t
.fn_ctxt .fn_ctxt
.tcx .tcx
.fn_sig(assoc.def_id) .fn_sig(assoc.def_id)
.instantiate(self.call_ctxt.fn_ctxt.tcx, args); .instantiate(self.call_ctxt.fn_ctxt.tcx, args)
.skip_norm_wip();
self.call_ctxt.fn_ctxt.instantiate_binder_with_fresh_vars( self.call_ctxt.fn_ctxt.instantiate_binder_with_fresh_vars(
call_name.span, call_name.span,
+13 -9
View File
@@ -17,7 +17,7 @@
}; };
use rustc_infer::infer::{self, RegionVariableOrigin}; use rustc_infer::infer::{self, RegionVariableOrigin};
use rustc_infer::traits::{DynCompatibilityViolation, Obligation}; use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span}; use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span};
use rustc_trait_selection::error_reporting::TypeErrCtxt; use rustc_trait_selection::error_reporting::TypeErrCtxt;
@@ -192,8 +192,8 @@ pub(crate) fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
typeck_results: Some(self.typeck_results.borrow()), typeck_results: Some(self.typeck_results.borrow()),
diverging_fallback_has_occurred: self.diverging_fallback_has_occurred.get(), diverging_fallback_has_occurred: self.diverging_fallback_has_occurred.get(),
normalize_fn_sig: Box::new(|fn_sig| { normalize_fn_sig: Box::new(|fn_sig| {
if fn_sig.has_escaping_bound_vars() { if fn_sig.skip_normalization().has_escaping_bound_vars() {
return fn_sig; return fn_sig.skip_normalization();
} }
self.probe(|_| { self.probe(|_| {
let ocx = ObligationCtxt::new(self); let ocx = ObligationCtxt::new(self);
@@ -205,7 +205,7 @@ pub(crate) fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
return normalized_fn_sig; return normalized_fn_sig;
} }
} }
fn_sig fn_sig.skip_normalization()
}) })
}), }),
autoderef_steps: Box::new(|ty| { autoderef_steps: Box::new(|ty| {
@@ -279,7 +279,7 @@ fn register_trait_ascription_bounds(
self.trait_ascriptions.borrow_mut().entry(hir_id.local_id).or_default().push(clause); self.trait_ascriptions.borrow_mut().entry(hir_id.local_id).or_default().push(clause);
let clause = self.normalize(span, clause); let clause = self.normalize(span, Unnormalized::new_wip(clause));
self.register_predicate(Obligation::new( self.register_predicate(Obligation::new(
self.tcx, self.tcx,
self.misc(span), self.misc(span),
@@ -326,7 +326,11 @@ fn select_inherent_assoc_candidates(
let mut filter_iat_candidate = |self_ty, impl_| { let mut filter_iat_candidate = |self_ty, impl_| {
let ocx = ObligationCtxt::new_with_diagnostics(self); let ocx = ObligationCtxt::new_with_diagnostics(self);
let self_ty = ocx.normalize(&ObligationCause::dummy(), self.param_env, self_ty); let self_ty = ocx.normalize(
&ObligationCause::dummy(),
self.param_env,
Unnormalized::new_wip(self_ty),
);
let impl_args = infcx.fresh_args_for_item(span, impl_); let impl_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);
@@ -410,7 +414,7 @@ fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
if self.next_trait_solver() { if self.next_trait_solver() {
self.try_structurally_resolve_type(span, ty).ty_adt_def() self.try_structurally_resolve_type(span, ty).ty_adt_def()
} else { } else {
self.normalize(span, ty).ty_adt_def() self.normalize(span, Unnormalized::new_wip(ty)).ty_adt_def()
} }
} }
_ => None, _ => None,
@@ -433,7 +437,7 @@ fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
self.add_required_obligations_for_hir(span, *def_id, args, hir_id); self.add_required_obligations_for_hir(span, *def_id, args, hir_id);
} }
self.normalize(span, ty) self.normalize(span, Unnormalized::new_wip(ty))
} else { } else {
ty ty
}; };
@@ -488,7 +492,7 @@ fn from_raw(fcx: &FnCtxt<'_, 'tcx>, span: Span, raw: Ty<'tcx>) -> LoweredTy<'tcx
let normalized = if fcx.next_trait_solver() { let normalized = if fcx.next_trait_solver() {
fcx.try_structurally_resolve_type(span, raw) fcx.try_structurally_resolve_type(span, raw)
} else { } else {
fcx.normalize(span, raw) fcx.normalize(span, Unnormalized::new_wip(raw))
}; };
LoweredTy { raw, normalized } LoweredTy { raw, normalized }
} }
@@ -19,7 +19,7 @@
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast, self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast,
suggest_constraining_type_params, suggest_constraining_type_params,
}; };
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
@@ -965,7 +965,7 @@ pub(in super::super) fn suggest_missing_return_type(
let bound_vars = let bound_vars =
self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id)); self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
let ty = Binder::bind_with_vars(ty, bound_vars); let ty = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize(hir_ty.span, ty); let ty = self.normalize(hir_ty.span, Unnormalized::new_wip(ty));
let ty = self.tcx.instantiate_bound_regions_with_erased(ty); let ty = self.tcx.instantiate_bound_regions_with_erased(ty);
if self.may_coerce(expected, ty) { if self.may_coerce(expected, ty) {
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other {
@@ -1231,7 +1231,7 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
} }
ty::Asyncness::No => ty, ty::Asyncness::No => ty,
}; };
let ty = self.normalize(expr.span, ty); let ty = self.normalize(expr.span, Unnormalized::new_wip(ty));
self.may_coerce(found, ty) self.may_coerce(found, ty)
} }
hir::FnRetTy::DefaultReturn(_) if in_closure => { hir::FnRetTy::DefaultReturn(_) if in_closure => {
@@ -1839,7 +1839,7 @@ pub(crate) fn suggest_associated_const(
// Same item // Same item
return false; return false;
} }
let item_ty = self.tcx.type_of(item.def_id).instantiate_identity(); let item_ty = self.tcx.type_of(item.def_id).instantiate_identity().skip_norm_wip();
// FIXME(compiler-errors): This check is *so* rudimentary // FIXME(compiler-errors): This check is *so* rudimentary
if item_ty.has_param() { if item_ty.has_param() {
return false; return false;
+4 -2
View File
@@ -5,7 +5,9 @@
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, LangItem};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_middle::ty::{
self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy, Unnormalized,
};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym}; use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
@@ -119,7 +121,7 @@ fn get_asm_ty(
} else { } else {
self.fcx.tcx.normalize_erasing_regions( self.fcx.tcx.normalize_erasing_regions(
self.fcx.typing_env(self.fcx.param_env), self.fcx.typing_env(self.fcx.param_env),
len, Unnormalized::new_wip(len),
) )
}; };
let Some(len) = len.try_to_target_usize(self.tcx()) else { let Some(len) = len.try_to_target_usize(self.tcx()) else {
+2 -2
View File
@@ -7,7 +7,7 @@
use rustc_index::Idx; use rustc_index::Idx;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized};
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use tracing::trace; use tracing::trace;
@@ -75,7 +75,7 @@ fn check_transmute<'tcx>(
) { ) {
let span = || tcx.hir_span(hir_id); let span = || tcx.hir_span(hir_id);
let normalize = |ty| { let normalize = |ty| {
if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) { if let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, Unnormalized::new_wip(ty)) {
ty ty
} else { } else {
Ty::new_error_with_message( Ty::new_error_with_message(
+9 -8
View File
@@ -50,7 +50,7 @@
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::config; use rustc_session::config;
use rustc_span::Span; use rustc_span::Span;
@@ -144,7 +144,7 @@ fn typeck_with_inspect<'tcx>(
// a suggestion later on. // a suggestion later on.
fcx.lowerer().lower_fn_ty(id, header.safety(), header.abi, decl, None, None) fcx.lowerer().lower_fn_ty(id, header.safety(), header.abi, decl, None, None)
} else { } else {
tcx.fn_sig(def_id).instantiate_identity() tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip()
}; };
check_abi(tcx, id, span, fn_sig.abi()); check_abi(tcx, id, span, fn_sig.abi());
@@ -168,7 +168,7 @@ fn typeck_with_inspect<'tcx>(
.inputs_and_output .inputs_and_output
.iter() .iter()
.enumerate() .enumerate()
.map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)), .map(|(idx, ty)| fcx.normalize(arg_span(idx), Unnormalized::new_wip(ty))),
); );
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) {
@@ -188,12 +188,12 @@ fn typeck_with_inspect<'tcx>(
// a suggestion later on. // a suggestion later on.
fcx.lowerer().lower_ty(ty) fcx.lowerer().lower_ty(ty)
} else { } else {
tcx.type_of(def_id).instantiate_identity() tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
}; };
loops::check(tcx, def_id, body); loops::check(tcx, def_id, body);
let expected_type = fcx.normalize(body.value.span, expected_type); let expected_type = fcx.normalize(body.value.span, Unnormalized::new_wip(expected_type));
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code); fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
@@ -244,7 +244,7 @@ fn typeck_with_inspect<'tcx>(
assert!(fcx.deferred_call_resolutions.borrow().is_empty()); assert!(fcx.deferred_call_resolutions.borrow().is_empty());
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) { for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
let ty = fcx.normalize(span, ty); let ty = fcx.normalize(span, Unnormalized::new_wip(ty));
fcx.require_type_is_sized(ty, span, code); fcx.require_type_is_sized(ty, span, code);
} }
@@ -408,14 +408,15 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
&& let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container && let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container
{ {
let impl_def_id = item.container_id(tcx); let impl_def_id = item.container_id(tcx);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate_identity(); let impl_trait_ref =
tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip();
let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto( let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
tcx, tcx,
impl_def_id, impl_def_id,
impl_trait_ref.args, impl_trait_ref.args,
); );
tcx.check_args_compatible(trait_item_def_id, args) tcx.check_args_compatible(trait_item_def_id, args)
.then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args)) .then(|| tcx.type_of(trait_item_def_id).instantiate(tcx, args).skip_norm_wip())
} else { } else {
Some(fcx.next_ty_var(span)) Some(fcx.next_ty_var(span))
} }
+27 -22
View File
@@ -23,7 +23,7 @@
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AssocContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, self, AssocContainer, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt,
TypeFoldable, TypeVisitableExt, UserArgs, TypeFoldable, TypeVisitableExt, Unnormalized, UserArgs,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Span}; use rustc_span::{DUMMY_SP, Span};
@@ -137,14 +137,15 @@ fn confirm(
// traits, no trait system method can be called before this point because they // traits, no trait system method can be called before this point because they
// could alter our Self-type, except for normalizing the receiver from the // could alter our Self-type, except for normalizing the receiver from the
// signature (which is also done during probing). // signature (which is also done during probing).
let method_sig_rcvr = self.normalize(self.span, method_sig.inputs()[0]); let method_sig_rcvr =
self.normalize(self.span, Unnormalized::new_wip(method_sig.inputs()[0]));
debug!( debug!(
"confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}", "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}",
self_ty, method_sig_rcvr, method_sig, method_predicates self_ty, method_sig_rcvr, method_sig, method_predicates
); );
self.unify_receivers(self_ty, method_sig_rcvr, pick); self.unify_receivers(self_ty, method_sig_rcvr, pick);
let method_sig = self.normalize(self.span, method_sig); let method_sig = self.normalize(self.span, Unnormalized::new_wip(method_sig));
// Make sure nobody calls `drop()` explicitly. // Make sure nobody calls `drop()` explicitly.
self.check_for_illegal_method_calls(pick); self.check_for_illegal_method_calls(pick);
@@ -460,7 +461,8 @@ fn provided_kind(
self.cfcx self.cfcx
.tcx .tcx
.type_of(param.def_id) .type_of(param.def_id)
.instantiate(self.cfcx.tcx, preceding_args), .instantiate(self.cfcx.tcx, preceding_args)
.skip_norm_wip(),
) )
.into(), .into(),
(GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
@@ -532,7 +534,7 @@ fn inferred_kind(
} }
} }
self.normalize(self.span, args) self.normalize(self.span, Unnormalized::new_wip(args))
} }
fn unify_receivers( fn unify_receivers(
@@ -591,7 +593,7 @@ fn instantiate_method_sig(
debug!("method_predicates after instantiation = {:?}", method_predicates); debug!("method_predicates after instantiation = {:?}", method_predicates);
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args); let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args).skip_norm_wip();
debug!("type scheme instantiated, sig={:?}", sig); debug!("type scheme instantiated, sig={:?}", sig);
let sig = self.instantiate_binder_with_fresh_vars(sig); let sig = self.instantiate_binder_with_fresh_vars(sig);
@@ -657,22 +659,25 @@ fn predicates_require_illegal_sized_bound(
) -> Option<Span> { ) -> Option<Span> {
let sized_def_id = self.tcx.lang_items().sized_trait()?; let sized_def_id = self.tcx.lang_items().sized_trait()?;
traits::elaborate(self.tcx, predicates.predicates.iter().copied()) traits::elaborate(
// We don't care about regions here. self.tcx,
.filter_map(|pred| match pred.kind().skip_binder() { predicates.predicates.iter().copied().map(Unnormalized::skip_norm_wip),
ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => { )
let span = predicates // We don't care about regions here.
.iter() .filter_map(|pred| match pred.kind().skip_binder() {
.find_map(|(p, span)| if p == pred { Some(span) } else { None }) ty::ClauseKind::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => {
.unwrap_or(DUMMY_SP); let span = predicates
Some((trait_pred, span)) .iter()
} .find_map(|(p, span)| if p.skip_norm_wip() == pred { Some(span) } else { None })
_ => None, .unwrap_or(DUMMY_SP);
}) Some((trait_pred, span))
.find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() { }
ty::Dynamic(..) => Some(span), _ => None,
_ => None, })
}) .find_map(|(trait_pred, span)| match trait_pred.self_ty().kind() {
ty::Dynamic(..) => Some(span),
_ => None,
})
} }
fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) { fn check_for_illegal_method_calls(&self, pick: &probe::Pick<'_>) {
+3 -3
View File
@@ -15,7 +15,7 @@
use rustc_infer::traits::PredicateObligations; use rustc_infer::traits::PredicateObligations;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt, self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt, Unnormalized,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
@@ -421,7 +421,7 @@ pub(super) fn lookup_method_for_operator(
// N.B., instantiate late-bound regions before normalizing the // N.B., instantiate late-bound regions before normalizing the
// function signature so that normalization does not need to deal // function signature so that normalization does not need to deal
// with bound regions. // with bound regions.
let fn_sig = tcx.fn_sig(def_id).instantiate(self.tcx, args); let fn_sig = tcx.fn_sig(def_id).instantiate(self.tcx, args).skip_norm_wip();
let fn_sig = self.instantiate_binder_with_fresh_vars( let fn_sig = self.instantiate_binder_with_fresh_vars(
obligation.cause.span, obligation.cause.span,
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
@@ -429,7 +429,7 @@ pub(super) fn lookup_method_for_operator(
); );
let InferOk { value: fn_sig, obligations: o } = let InferOk { value: fn_sig, obligations: o } =
self.at(&obligation.cause, self.param_env).normalize(fn_sig); self.at(&obligation.cause, self.param_env).normalize(Unnormalized::new_wip(fn_sig));
obligations.extend(o); obligations.extend(o);
// Register obligations for the parameters. This will include the // Register obligations for the parameters. This will include the
+23 -12
View File
@@ -18,7 +18,7 @@
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AssocContainer, AssocItem, GenericArgs, GenericArgsRef, GenericParamDefKind, ParamEnvAnd, self, AssocContainer, AssocItem, GenericArgs, GenericArgsRef, GenericParamDefKind, ParamEnvAnd,
Ty, TyCtxt, TypeVisitableExt, Upcast, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint; use rustc_session::lint;
@@ -1073,7 +1073,8 @@ fn matches_return_type(&self, method: ty::AssocItem, expected: Ty<'tcx>) -> bool
match method.kind { match method.kind {
ty::AssocKind::Fn { .. } => self.probe(|_| { ty::AssocKind::Fn { .. } => self.probe(|_| {
let args = self.fresh_args_for_item(self.span, method.def_id); let args = self.fresh_args_for_item(self.span, method.def_id);
let fty = self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args); let fty =
self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args).skip_norm_wip();
let fty = self.instantiate_binder_with_fresh_vars( let fty = self.instantiate_binder_with_fresh_vars(
self.span, self.span,
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
@@ -1971,10 +1972,15 @@ fn consider_probe(
match probe.kind { match probe.kind {
InherentImplCandidate { impl_def_id, .. } => { InherentImplCandidate { impl_def_id, .. } => {
let impl_args = self.fresh_args_for_item(self.span, impl_def_id); let impl_args = self.fresh_args_for_item(self.span, impl_def_id);
let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args); let impl_ty = self
.tcx
.type_of(impl_def_id)
.instantiate(self.tcx, impl_args)
.skip_norm_wip();
(xform_self_ty, xform_ret_ty) = (xform_self_ty, xform_ret_ty) =
self.xform_self_ty(probe.item, impl_ty, impl_args); self.xform_self_ty(probe.item, impl_ty, impl_args);
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); xform_self_ty =
ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty));
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
{ {
Ok(()) => {} Ok(()) => {}
@@ -1984,7 +1990,8 @@ fn consider_probe(
} }
} }
// FIXME: Weirdly, we normalize the ret ty in this candidate, but no other candidates. // FIXME: Weirdly, we normalize the ret ty in this candidate, but no other candidates.
xform_ret_ty = ocx.normalize(cause, self.param_env, xform_ret_ty); xform_ret_ty =
ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_ret_ty));
// Check whether the impl imposes obligations we have to worry about. // Check whether the impl imposes obligations we have to worry about.
let impl_def_id = probe.item.container_id(self.tcx); let impl_def_id = probe.item.container_id(self.tcx);
let impl_bounds = let impl_bounds =
@@ -2033,10 +2040,12 @@ fn consider_probe(
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
poly_trait_ref, poly_trait_ref,
); );
let trait_ref = ocx.normalize(cause, self.param_env, trait_ref); let trait_ref =
ocx.normalize(cause, self.param_env, Unnormalized::new_wip(trait_ref));
(xform_self_ty, xform_ret_ty) = (xform_self_ty, xform_ret_ty) =
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); xform_self_ty =
ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty));
match self_ty.kind() { match self_ty.kind() {
// HACK: opaque types will match anything for which their bounds hold. // HACK: opaque types will match anything for which their bounds hold.
// Thus we need to prevent them from trying to match the `&_` autoref // Thus we need to prevent them from trying to match the `&_` autoref
@@ -2106,7 +2115,7 @@ fn consider_probe(
match ocx.structurally_normalize_ty( match ocx.structurally_normalize_ty(
cause, cause,
self.param_env, self.param_env,
trait_ref.self_ty(), Unnormalized::new_wip(trait_ref.self_ty()),
) { ) {
Ok(ty) => { Ok(ty) => {
if !matches!(ty.kind(), ty::Param(_)) { if !matches!(ty.kind(), ty::Param(_)) {
@@ -2121,7 +2130,8 @@ fn consider_probe(
} }
} }
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); xform_self_ty =
ocx.normalize(cause, self.param_env, Unnormalized::new_wip(xform_self_ty));
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty) match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
{ {
Ok(()) => {} Ok(()) => {}
@@ -2184,7 +2194,8 @@ fn consider_probe(
// but `self.return_type` is only set on the diagnostic-path, so we // but `self.return_type` is only set on the diagnostic-path, so we
// should be okay doing it here. // should be okay doing it here.
if !matches!(probe.kind, InherentImplCandidate { .. }) { if !matches!(probe.kind, InherentImplCandidate { .. }) {
xform_ret_ty = ocx.normalize(&cause, self.param_env, xform_ret_ty); xform_ret_ty =
ocx.normalize(&cause, self.param_env, Unnormalized::new_wip(xform_ret_ty));
} }
debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty); debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty);
@@ -2558,7 +2569,7 @@ fn xform_method_sig(&self, method: DefId, args: GenericArgsRef<'tcx>) -> ty::FnS
assert_eq!(args.len(), generics.parent_count); assert_eq!(args.len(), generics.parent_count);
let xform_fn_sig = if generics.is_own_empty() { let xform_fn_sig = if generics.is_own_empty() {
fn_sig.instantiate(self.tcx, args) fn_sig.instantiate(self.tcx, args).skip_norm_wip()
} else { } else {
let args = GenericArgs::for_item(self.tcx, method, |param, _| { let args = GenericArgs::for_item(self.tcx, method, |param, _| {
let i = param.index as usize; let i = param.index as usize;
@@ -2576,7 +2587,7 @@ fn xform_method_sig(&self, method: DefId, args: GenericArgsRef<'tcx>) -> ty::FnS
} }
} }
}); });
fn_sig.instantiate(self.tcx, args) fn_sig.instantiate(self.tcx, args).skip_norm_wip()
}; };
self.tcx.instantiate_bound_regions_with_erased(xform_fn_sig) self.tcx.instantiate_bound_regions_with_erased(xform_fn_sig)
+45 -19
View File
@@ -478,7 +478,8 @@ fn create_no_assoc_err(
}); });
let has_deref = autoderef.step_count() > 0; let has_deref = autoderef.step_count() > 0;
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
ty = self.tcx.at(span).type_of(def.did()).instantiate_identity(); ty =
self.tcx.at(span).type_of(def.did()).instantiate_identity().skip_norm_wip();
} }
} }
} }
@@ -1406,7 +1407,11 @@ fn set_not_found_span_label(
// different from the received one // different from the received one
// So we avoid suggestion method with Box<Self> // So we avoid suggestion method with Box<Self>
// for instance // for instance
self.tcx.at(span).type_of(*def_id).instantiate_identity() self.tcx
.at(span)
.type_of(*def_id)
.instantiate_identity()
.skip_norm_wip()
!= rcvr_ty != rcvr_ty
} }
(Mode::Path, false, _) => true, (Mode::Path, false, _) => true,
@@ -1425,7 +1430,12 @@ fn set_not_found_span_label(
vec![ vec![
StringPart::normal(format!("the {item_kind} was found for `")), StringPart::normal(format!("the {item_kind} was found for `")),
StringPart::highlighted( StringPart::highlighted(
self.tcx.at(span).type_of(*only).instantiate_identity().to_string(), self.tcx
.at(span)
.type_of(*only)
.instantiate_identity()
.skip_norm_wip()
.to_string(),
), ),
StringPart::normal(format!("`")), StringPart::normal(format!("`")),
] ]
@@ -1439,7 +1449,11 @@ fn set_not_found_span_label(
.map(|impl_item| { .map(|impl_item| {
format!( format!(
"- `{}`", "- `{}`",
self.tcx.at(span).type_of(*impl_item).instantiate_identity() self.tcx
.at(span)
.type_of(*impl_item)
.instantiate_identity()
.skip_norm_wip()
) )
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
@@ -1534,7 +1548,7 @@ fn suggest_enum_variant_for_method_call(
suggestion = vec![(replacement_span, var_name.to_string())]; suggestion = vec![(replacement_span, var_name.to_string())];
} }
(Some((hir::def::CtorKind::Fn, def_id)), hir::ExprKind::Call(rcvr, args)) => { (Some((hir::def::CtorKind::Fn, def_id)), hir::ExprKind::Call(rcvr, args)) => {
let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let inputs = fn_sig.inputs().skip_binder(); let inputs = fn_sig.inputs().skip_binder();
// FIXME: reuse the logic for "change args" suggestion to account for types // FIXME: reuse the logic for "change args" suggestion to account for types
// involved and detect things like substitution. // involved and detect things like substitution.
@@ -1580,7 +1594,7 @@ fn suggest_enum_variant_for_method_call(
} }
} }
(Some((hir::def::CtorKind::Fn, def_id)), _) => { (Some((hir::def::CtorKind::Fn, def_id)), _) => {
let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); let fn_sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip();
let inputs = fn_sig.inputs().skip_binder(); let inputs = fn_sig.inputs().skip_binder();
suggestion = vec![( suggestion = vec![(
replacement_span, replacement_span,
@@ -2204,7 +2218,8 @@ fn find_likely_intended_associated_item(
// not methods because they dont have an instance of the struct to work with. // not methods because they dont have an instance of the struct to work with.
if def_kind == DefKind::AssocFn { if def_kind == DefKind::AssocFn {
let ty_args = self.infcx.fresh_args_for_item(span, similar_candidate.def_id); let ty_args = self.infcx.fresh_args_for_item(span, similar_candidate.def_id);
let fn_sig = tcx.fn_sig(similar_candidate.def_id).instantiate(tcx, ty_args); let fn_sig =
tcx.fn_sig(similar_candidate.def_id).instantiate(tcx, ty_args).skip_norm_wip();
let fn_sig = self.instantiate_binder_with_fresh_vars( let fn_sig = self.instantiate_binder_with_fresh_vars(
span, span,
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
@@ -2287,8 +2302,11 @@ pub(crate) fn confusable_method_name(
inherent_method.container_id(self.tcx), inherent_method.container_id(self.tcx),
adt_args, adt_args,
); );
let fn_sig = let fn_sig = self
self.tcx.fn_sig(inherent_method.def_id).instantiate(self.tcx, args); .tcx
.fn_sig(inherent_method.def_id)
.instantiate(self.tcx, args)
.skip_norm_wip();
let fn_sig = self.instantiate_binder_with_fresh_vars( let fn_sig = self.instantiate_binder_with_fresh_vars(
item_name.span, item_name.span,
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
@@ -2363,7 +2381,8 @@ fn note_candidates_on_method_error(
None None
}; };
let impl_ty = self.tcx.at(span).type_of(impl_did).instantiate_identity(); let impl_ty =
self.tcx.at(span).type_of(impl_did).instantiate_identity().skip_norm_wip();
let insertion = match self.tcx.impl_opt_trait_ref(impl_did) { let insertion = match self.tcx.impl_opt_trait_ref(impl_did) {
None => String::new(), None => String::new(),
@@ -2411,6 +2430,7 @@ fn note_candidates_on_method_error(
self.tcx, self.tcx,
self.fresh_args_for_item(sugg_span, impl_did), self.fresh_args_for_item(sugg_span, impl_did),
) )
.skip_norm_wip()
.with_replaced_self_ty(self.tcx, rcvr_ty), .with_replaced_self_ty(self.tcx, rcvr_ty),
idx, idx,
sugg_span, sugg_span,
@@ -2510,6 +2530,7 @@ fn find_builder_fn(&self, err: &mut Diag<'_>, rcvr_ty: Ty<'tcx>, expr_id: hir::H
.tcx .tcx
.fn_sig(item.def_id) .fn_sig(item.def_id)
.instantiate(self.tcx, self.fresh_args_for_item(DUMMY_SP, item.def_id)) .instantiate(self.tcx, self.fresh_args_for_item(DUMMY_SP, item.def_id))
.skip_norm_wip()
.output(); .output();
let ret_ty = self.tcx.instantiate_bound_regions_with_erased(ret_ty); let ret_ty = self.tcx.instantiate_bound_regions_with_erased(ret_ty);
let ty::Adt(def, args) = ret_ty.kind() else { let ty::Adt(def, args) = ret_ty.kind() else {
@@ -2591,7 +2612,7 @@ fn suggest_associated_call_syntax(
// When the "method" is resolved through dereferencing, we really want the // When the "method" is resolved through dereferencing, we really want the
// original type that has the associated function for accurate suggestions. // original type that has the associated function for accurate suggestions.
// (#61411) // (#61411)
let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity(); let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity().skip_norm_wip();
let target_ty = self let target_ty = self
.autoderef(sugg_span, rcvr_ty) .autoderef(sugg_span, rcvr_ty)
.silence_errors() .silence_errors()
@@ -2628,9 +2649,10 @@ fn suggest_associated_call_syntax(
if let SelfSource::MethodCall(_) = source { if let SelfSource::MethodCall(_) = source {
let first_arg = static_candidates.get(0).and_then(|candidate_source| { let first_arg = static_candidates.get(0).and_then(|candidate_source| {
let (assoc_did, self_ty) = match candidate_source { let (assoc_did, self_ty) = match candidate_source {
CandidateSource::Impl(impl_did) => { CandidateSource::Impl(impl_did) => (
(*impl_did, self.tcx.type_of(*impl_did).instantiate_identity()) *impl_did,
} self.tcx.type_of(*impl_did).instantiate_identity().skip_norm_wip(),
),
CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty), CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty),
}; };
@@ -2641,7 +2663,7 @@ fn suggest_associated_call_syntax(
// for CandidateSource::Impl, `Self` will be instantiated to a concrete type // for CandidateSource::Impl, `Self` will be instantiated to a concrete type
// but for CandidateSource::Trait, `Self` is still `Self` // but for CandidateSource::Trait, `Self` is still `Self`
let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity(); let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity().skip_norm_wip();
sig.inputs().skip_binder().get(0).and_then(|first| { 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 // 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(); let first_ty = first.peel_refs();
@@ -2826,8 +2848,11 @@ fn report_failed_method_call_on_range_end(
else { else {
continue; continue;
}; };
let range_ty = let range_ty = self
self.tcx.type_of(range_def_id).instantiate(self.tcx, &[actual.into()]); .tcx
.type_of(range_def_id)
.instantiate(self.tcx, &[actual.into()])
.skip_norm_wip();
let pick = self.lookup_probe_for_diagnostic( let pick = self.lookup_probe_for_diagnostic(
item_name, item_name,
@@ -3492,6 +3517,7 @@ fn consider_suggesting_derives_for_ty(
self.tcx self.tcx
.type_of(impl_def_id) .type_of(impl_def_id)
.instantiate_identity() .instantiate_identity()
.skip_norm_wip()
.ty_adt_def() .ty_adt_def()
.is_some_and(|def| def.did() == adt.did()) .is_some_and(|def| def.did() == adt.did())
}) { }) {
@@ -3623,7 +3649,7 @@ fn note_derefed_ty_has_method(
// just changing the path. // just changing the path.
&& pick.item.is_method() && pick.item.is_method()
&& let Some(self_ty) = && let Some(self_ty) =
self.tcx.fn_sig(pick.item.def_id).instantiate_identity().inputs().skip_binder().get(0) self.tcx.fn_sig(pick.item.def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder().get(0)
&& self_ty.is_ref() && self_ty.is_ref()
{ {
let suggested_path = match deref_ty.kind() { let suggested_path = match deref_ty.kind() {
@@ -4585,7 +4611,7 @@ enum Introducer {
.map(|imp_did| self.tcx.impl_trait_header(imp_did)) .map(|imp_did| self.tcx.impl_trait_header(imp_did))
.filter(|header| header.polarity != ty::ImplPolarity::Positive) .filter(|header| header.polarity != ty::ImplPolarity::Positive)
.any(|header| { .any(|header| {
let imp = header.trait_ref.instantiate_identity(); let imp = header.trait_ref.instantiate_identity().skip_norm_wip();
let imp_simp = let imp_simp =
simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid); simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid);
imp_simp.is_some_and(|s| s == simp_rcvr_ty) imp_simp.is_some_and(|s| s == simp_rcvr_ty)
@@ -3,7 +3,7 @@
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType, self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType,
TypeVisitableExt, TypeVisitableExt, Unnormalized,
}; };
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
use rustc_trait_selection::opaque_types::{ use rustc_trait_selection::opaque_types::{
@@ -139,7 +139,7 @@ fn compute_definition_site_hidden_types(
continue; continue;
} }
let expected = ty.ty.instantiate(tcx, opaque_type_key.args); let expected = ty.ty.instantiate(tcx, opaque_type_key.args).skip_norm_wip();
self.demand_eqtype(hidden_type.span, expected, hidden_type.ty); self.demand_eqtype(hidden_type.span, expected, hidden_type.ty);
} }
@@ -236,7 +236,7 @@ fn consider_opaque_type_use(
let cause = ObligationCause::misc(hidden_type.span, self.body_id); let cause = ObligationCause::misc(hidden_type.span, self.body_id);
let at = self.at(&cause, self.param_env); let at = self.at(&cause, self.param_env);
let hidden_type = match solve::deeply_normalize(at, hidden_type) { let hidden_type = match solve::deeply_normalize(at, Unnormalized::new_wip(hidden_type)) {
Ok(hidden_type) => hidden_type, Ok(hidden_type) => hidden_type,
Err(errors) => { Err(errors) => {
let guar = self.err_ctxt().report_fulfillment_errors(errors); let guar = self.err_ctxt().report_fulfillment_errors(errors);
+2 -2
View File
@@ -19,7 +19,7 @@
use rustc_hir_analysis::autoderef::report_autoderef_recursion_limit_error; use rustc_hir_analysis::autoderef::report_autoderef_recursion_limit_error;
use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::RegionVariableOrigin;
use rustc_middle::traits::PatternOriginExpr; use rustc_middle::traits::PatternOriginExpr;
use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Pinnedness, Ty, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
@@ -2704,7 +2704,7 @@ fn deref_pat_target(&self, span: Span, source_ty: Ty<'tcx>) -> Ty<'tcx> {
tcx.require_lang_item(hir::LangItem::DerefTarget, span), tcx.require_lang_item(hir::LangItem::DerefTarget, span),
[source_ty], [source_ty],
); );
let target_ty = self.normalize(span, target_ty); let target_ty = self.normalize(span, Unnormalized::new_wip(target_ty));
self.try_structurally_resolve_type(span, target_ty) self.try_structurally_resolve_type(span, target_ty)
} }
+3 -3
View File
@@ -44,7 +44,7 @@
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{ use rustc_middle::ty::{
self, BorrowKind, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, self, BorrowKind, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults,
UpvarArgs, UpvarCapture, Unnormalized, UpvarArgs, UpvarCapture,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint; use rustc_session::lint;
@@ -1182,7 +1182,7 @@ fn normalize_capture_place(&self, span: Span, place: Place<'tcx>) -> Place<'tcx>
let at = self.at(&cause, self.param_env); let at = self.at(&cause, self.param_env);
match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
at, at,
place.clone(), Unnormalized::new_wip(place.clone()),
vec![], vec![],
) { ) {
Ok((normalized, goals)) => { Ok((normalized, goals)) => {
@@ -1208,7 +1208,7 @@ fn normalize_capture_place(&self, span: Span, place: Place<'tcx>) -> Place<'tcx>
} }
} else { } else {
// For the old solver we can rely on `normalize` to eagerly normalize aliases. // For the old solver we can rely on `normalize` to eagerly normalize aliases.
self.normalize(span, place) self.normalize(span, Unnormalized::new_wip(place))
} }
} }
+9 -4
View File
@@ -23,7 +23,7 @@
use rustc_middle::ty::{ use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder, self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
fold_regions, Unnormalized, fold_regions,
}; };
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
@@ -623,6 +623,7 @@ fn visit_opaque_types(&mut self) {
hidden_ty hidden_ty
.ty .ty
.instantiate_identity() .instantiate_identity()
.skip_norm_wip()
.visit_with(&mut HasRecursiveOpaque { .visit_with(&mut HasRecursiveOpaque {
def_id, def_id,
seen: Default::default(), seen: Default::default(),
@@ -947,7 +948,9 @@ fn handle_term<T>(
let at = self.fcx.at(&cause, self.fcx.param_env); let at = self.fcx.at(&cause, self.fcx.param_env);
let universes = vec![None; outer_exclusive_binder(value).as_usize()]; let universes = vec![None; outer_exclusive_binder(value).as_usize()];
match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals( match solve::deeply_normalize_with_skipped_universes_and_ambiguous_coroutine_goals(
at, value, universes, at,
Unnormalized::new_wip(value),
universes,
) { ) {
Ok((value, goals)) => { Ok((value, goals)) => {
self.nested_goals.extend(goals); self.nested_goals.extend(goals);
@@ -1035,7 +1038,9 @@ fn cx(&self) -> TyCtxt<'tcx> {
} }
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
self.tcx.try_normalize_erasing_regions(self.typing_env, ct).unwrap_or(ct) self.tcx
.try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(ct))
.unwrap_or(ct)
} }
} }
@@ -1060,7 +1065,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
if self.seen.insert(def_id) if self.seen.insert(def_id)
&& let Some(hidden_ty) = self.opaques.get(&def_id) && let Some(hidden_ty) = self.opaques.get(&def_id)
{ {
hidden_ty.ty.instantiate(self.tcx, args).visit_with(self)?; hidden_ty.ty.instantiate(self.tcx, args).skip_norm_wip().visit_with(self)?;
} }
} }
@@ -6,7 +6,7 @@
use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable, self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable,
TypeVisitableExt, TypeVisitableExt, Unnormalized,
}; };
use rustc_span::Span; use rustc_span::Span;
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@@ -264,7 +264,8 @@ pub fn insert_hidden_type(
let actual = prev.unwrap_or_else(|| { let actual = prev.unwrap_or_else(|| {
let actual = tcx let actual = tcx
.type_of_opaque_hir_typeck(opaque_type_key.def_id) .type_of_opaque_hir_typeck(opaque_type_key.def_id)
.instantiate(self.tcx, opaque_type_key.args); .instantiate(self.tcx, opaque_type_key.args)
.skip_norm_wip();
let actual = ty::fold_regions(tcx, actual, |re, _dbi| match re.kind() { let actual = ty::fold_regions(tcx, actual, |re, _dbi| match re.kind() {
ty::ReErased => self.next_region_var(RegionVariableOrigin::Misc(span)), ty::ReErased => self.next_region_var(RegionVariableOrigin::Misc(span)),
_ => re, _ => re,
@@ -352,7 +353,9 @@ pub fn add_item_bounds_for_hidden_type(
}; };
let item_bounds = tcx.explicit_item_bounds(def_id); let item_bounds = tcx.explicit_item_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { for (predicate, _) in
item_bounds.iter_instantiated_copied(tcx, args).map(Unnormalized::skip_norm_wip)
{
let predicate = replace_opaques_in(predicate, goals); let predicate = replace_opaques_in(predicate, goals);
// Require that the predicate holds for the concrete type. // Require that the predicate holds for the concrete type.
@@ -363,7 +366,9 @@ pub fn add_item_bounds_for_hidden_type(
// If this opaque is being defined and it's conditionally const, // If this opaque is being defined and it's conditionally const,
if self.tcx.is_conditionally_const(def_id) { if self.tcx.is_conditionally_const(def_id) {
let item_bounds = tcx.explicit_implied_const_bounds(def_id); let item_bounds = tcx.explicit_implied_const_bounds(def_id);
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { for (predicate, _) in
item_bounds.iter_instantiated_copied(tcx, args).map(Unnormalized::skip_norm_wip)
{
let predicate = replace_opaques_in( let predicate = replace_opaques_in(
predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe), predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe),
goals, goals,
@@ -1,5 +1,6 @@
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
Unnormalized,
}; };
use crate::infer::outlives::test_type_match; use crate::infer::outlives::test_type_match;
@@ -61,6 +62,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
let outlives_bounds: Vec<_> = tcx let outlives_bounds: Vec<_> = tcx
.item_bounds(kind.def_id()) .item_bounds(kind.def_id())
.iter_instantiated(tcx, args) .iter_instantiated(tcx, args)
.map(Unnormalized::skip_norm_wip)
.chain(param_env.caller_bounds()) .chain(param_env.caller_bounds())
.filter_map(|clause| { .filter_map(|clause| {
let outlives = clause.as_type_outlives_clause()?; let outlives = clause.as_type_outlives_clause()?;
@@ -1,7 +1,7 @@
use std::assert_matches; use std::assert_matches;
use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive}; 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 smallvec::smallvec;
use tracing::{debug, instrument, trace}; use tracing::{debug, instrument, trace};
@@ -285,6 +285,7 @@ pub(crate) fn declared_bounds_from_definition(
trace!("{:#?}", bounds.skip_binder()); trace!("{:#?}", bounds.skip_binder());
bounds bounds
.iter_instantiated(tcx, alias_ty.args) .iter_instantiated(tcx, alias_ty.args)
.map(Unnormalized::skip_norm_wip)
.filter_map(|p| p.as_type_outlives_clause()) .filter_map(|p| p.as_type_outlives_clause())
.filter_map(|p| p.no_bound_vars()) .filter_map(|p| p.no_bound_vars())
.map(|OutlivesPredicate(_, r)| r) .map(|OutlivesPredicate(_, r)| r)
+2 -1
View File
@@ -1,6 +1,6 @@
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
pub use rustc_middle::ty::elaborate::*; 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 rustc_span::{Ident, Span};
use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
@@ -123,6 +123,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
stack.extend( stack.extend(
tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name)) tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name))
.iter_identity_copied() .iter_identity_copied()
.map(Unnormalized::skip_norm_wip)
.map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref)) .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref))
.filter_map(|clause| clause.as_trait_clause()) .filter_map(|clause| clause.as_trait_clause())
.filter(|clause| clause.polarity() == ty::PredicatePolarity::Positive) .filter(|clause| clause.polarity() == ty::PredicatePolarity::Positive)
+1 -1
View File
@@ -1171,7 +1171,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
// Eagerly check the unsubstituted layout for cycles. // Eagerly check the unsubstituted layout for cycles.
tcx.ensure_ok().layout_of( tcx.ensure_ok().layout_of(
ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) ty::TypingEnv::post_analysis(tcx, def_id.to_def_id())
.as_query_input(tcx.type_of(def_id).instantiate_identity()), .as_query_input(tcx.type_of(def_id).instantiate_identity().skip_norm_wip()),
); );
} }
}); });
+14 -6
View File
@@ -33,7 +33,9 @@
use rustc_middle::lint::LevelAndSource; use rustc_middle::lint::LevelAndSource;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef}; use rustc_middle::ty::{
self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast, VariantDef,
};
// hardwired lints from rustc_lint_defs // hardwired lints from rustc_lint_defs
pub use rustc_session::lint::builtin::*; pub use rustc_session::lint::builtin::*;
use rustc_session::lint::fcw; use rustc_session::lint::fcw;
@@ -464,7 +466,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
// If the method is an impl for an item with docs_hidden, don't doc. // If the method is an impl for an item with docs_hidden, don't doc.
AssocContainer::InherentImpl => { AssocContainer::InherentImpl => {
let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()); let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id());
let impl_ty = cx.tcx.type_of(parent).instantiate_identity(); let impl_ty = cx.tcx.type_of(parent).instantiate_identity().skip_norm_wip();
let outerdef = match impl_ty.kind() { let outerdef = match impl_ty.kind() {
ty::Adt(def, _) => Some(def.did()), ty::Adt(def, _) => Some(def.did()),
ty::Foreign(def_id) => Some(*def_id), ty::Foreign(def_id) => Some(*def_id),
@@ -573,7 +575,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
// and recommending Copy might be a bad idea. // and recommending Copy might be a bad idea.
for field in def.all_fields() { for field in def.all_fields() {
let did = field.did; let did = field.did;
if cx.tcx.type_of(did).instantiate_identity().is_raw_ptr() { if cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().is_raw_ptr() {
return; return;
} }
} }
@@ -703,7 +705,10 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
let has_impl = cx let has_impl = cx
.tcx .tcx
.non_blanket_impls_for_ty(debug, cx.tcx.type_of(item.owner_id).instantiate_identity()) .non_blanket_impls_for_ty(
debug,
cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip(),
)
.next() .next()
.is_some(); .is_some();
if !has_impl { if !has_impl {
@@ -1376,7 +1381,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
// FIXME(generic_const_exprs): Revisit this before stabilization. // FIXME(generic_const_exprs): Revisit this before stabilization.
// See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`.
let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ty = cx.tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip();
if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)
&& cx.tcx.features().generic_const_exprs() && cx.tcx.features().generic_const_exprs()
{ {
@@ -2523,7 +2528,10 @@ fn ty_find_init_error<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
init: InitKind, init: InitKind,
) -> Option<InitError> { ) -> Option<InitError> {
let ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty); let ty = cx
.tcx
.try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(ty))
.unwrap_or(ty);
match ty.kind() { match ty.kind() {
// Primitive types that don't like 0 as a value. // Primitive types that don't like 0 as a value.
+5 -2
View File
@@ -24,7 +24,9 @@
use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode}; use rustc_middle::ty::{
self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode, Unnormalized,
};
use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintExpectationId, LintId}; use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintExpectationId, LintId};
use rustc_session::{DynLintStore, Session}; use rustc_session::{DynLintStore, Session};
use rustc_span::edit_distance::find_best_match_for_names; use rustc_span::edit_distance::find_best_match_for_names;
@@ -833,7 +835,8 @@ pub fn get_associated_type(
.find_by_ident_and_kind(tcx, Ident::with_dummy_span(name), ty::AssocTag::Type, trait_id) .find_by_ident_and_kind(tcx, Ident::with_dummy_span(name), ty::AssocTag::Type, trait_id)
.and_then(|assoc| { .and_then(|assoc| {
let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]); let proj = Ty::new_projection(tcx, assoc.def_id, [self_ty]);
tcx.try_normalize_erasing_regions(self.typing_env(), proj).ok() tcx.try_normalize_erasing_regions(self.typing_env(), Unnormalized::new_wip(proj))
.ok()
}) })
} }
+2 -2
View File
@@ -102,8 +102,8 @@ fn check_fn(
&& let TyKind::Ptr(_) = ret_ty.kind && let TyKind::Ptr(_) = ret_ty.kind
{ {
// get the return type of the function or closure // get the return type of the function or closure
let ty = match cx.tcx.type_of(def_id).instantiate_identity().kind() { let ty = match cx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().kind() {
ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity(), ty::FnDef(..) => cx.tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(),
ty::Closure(_, args) => args.as_closure().sig(), ty::Closure(_, args) => args.as_closure().sig(),
_ => return, _ => return,
}; };
@@ -67,7 +67,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_
// We don't care about what `#[derive(Default)]` produces in this lint. // We don't care about what `#[derive(Default)]` produces in this lint.
return; return;
} }
let ty = cx.tcx.type_of(impl_id).instantiate_identity(); let ty = cx.tcx.type_of(impl_id).instantiate_identity().skip_norm_wip();
let ty::Adt(def, _) = ty.kind() else { return }; let ty::Adt(def, _) = ty.kind() else { return };
// We now know we have a manually written definition of a `<Type as Default>::default()`. // We now know we have a manually written definition of a `<Type as Default>::default()`.
@@ -65,7 +65,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
&& let Some(did) = of_trait.trait_ref.trait_def_id() && let Some(did) = of_trait.trait_ref.trait_def_id()
&& tcx.is_lang_item(did, LangItem::Deref) && tcx.is_lang_item(did, LangItem::Deref)
// the self type is `dyn t_principal` // the self type is `dyn t_principal`
&& let self_ty = tcx.type_of(item.owner_id).instantiate_identity() && let self_ty = tcx.type_of(item.owner_id).instantiate_identity().skip_norm_wip()
&& let ty::Dynamic(data, _) = self_ty.kind() && let ty::Dynamic(data, _) = self_ty.kind()
&& let Some(self_principal) = data.principal() && let Some(self_principal) = data.principal()
// `<T as Deref>::Target` is `dyn target_principal` // `<T as Deref>::Target` is `dyn target_principal`
@@ -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))); return Some(format!("{}{}", name, gen_args(cx, path_segment)));
} }
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { if let ty::Adt(adt, args) =
cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
{
if find_attr!(cx.tcx, adt.did(), RustcPassByValue(_)) { if find_attr!(cx.tcx, adt.did(), RustcPassByValue(_)) {
return Some(cx.tcx.def_path_str_with_args(adt.did(), args)); return Some(cx.tcx.def_path_str_with_args(adt.did(), args));
} }
+3 -3
View File
@@ -123,7 +123,7 @@ fn check_foreign_item<'tcx>(&mut self, tcx: TyCtxt<'tcx>, this_fi: hir::ForeignI
let Some(existing_did) = self.insert(tcx, this_fi) else { return }; let Some(existing_did) = self.insert(tcx, this_fi) else { return };
let existing_decl_ty = tcx.type_of(existing_did).skip_binder(); let existing_decl_ty = tcx.type_of(existing_did).skip_binder();
let this_decl_ty = tcx.type_of(this_fi.owner_id).instantiate_identity(); let this_decl_ty = tcx.type_of(this_fi.owner_id).instantiate_identity().skip_norm_wip();
debug!( debug!(
"ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}", "ClashingExternDeclarations: Comparing existing {:?}: {:?} to this {:?}: {:?}",
existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty existing_did, existing_decl_ty, this_fi.owner_id, this_decl_ty
@@ -297,8 +297,8 @@ fn structurally_same_type_impl<'tcx>(
seen_types, seen_types,
tcx, tcx,
typing_env, typing_env,
tcx.type_of(a_did).instantiate(tcx, a_gen_args), tcx.type_of(a_did).instantiate(tcx, a_gen_args).skip_norm_wip(),
tcx.type_of(b_did).instantiate(tcx, b_gen_args), tcx.type_of(b_did).instantiate(tcx, b_gen_args).skip_norm_wip(),
) )
}, },
) )
+1 -1
View File
@@ -166,7 +166,7 @@ fn check_fn(
return; return;
} }
let sig = cx.tcx.fn_sig(id).instantiate_identity(); let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_norm_wip();
let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); let sig = cx.tcx.instantiate_bound_regions_with_erased(sig);
for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) {
@@ -17,6 +17,7 @@
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
Unnormalized,
}; };
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_session::lint::fcw; use rustc_session::lint::fcw;
@@ -141,7 +142,7 @@ enum ParamKind {
} }
fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) {
let sig = tcx.fn_sig(parent_def_id).instantiate_identity(); let sig = tcx.fn_sig(parent_def_id).instantiate_identity().skip_norm_wip();
let mut in_scope_parameters = FxIndexMap::default(); let mut in_scope_parameters = FxIndexMap::default();
// Populate the in_scope_parameters list first with all of the generics in scope // Populate the in_scope_parameters list first with all of the generics in scope
@@ -246,7 +247,7 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
&& self.tcx.is_impl_trait_in_trait(def_id) && self.tcx.is_impl_trait_in_trait(def_id)
{ {
// visit the opaque of the RPITIT // visit the opaque of the RPITIT
self.tcx.type_of(def_id).instantiate(self.tcx, args).visit_with(self) self.tcx.type_of(def_id).instantiate(self.tcx, args).skip_norm_wip().visit_with(self)
} else if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args: opaque_ty_args, .. }) = *t.kind() } else if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args: opaque_ty_args, .. }) = *t.kind()
&& let Some(opaque_def_id) = def_id.as_local() && let Some(opaque_def_id) = def_id.as_local()
// Don't recurse infinitely on an opaque // Don't recurse infinitely on an opaque
@@ -412,7 +413,12 @@ fn visit_ty(&mut self, t: Ty<'tcx>) {
// in this lint as well. Interestingly, one place that I expect this lint to fire // in this lint as well. Interestingly, one place that I expect this lint to fire
// is for `impl for<'a> Bound<Out = impl Other>`, since `impl Other` will begin // is for `impl for<'a> Bound<Out = impl Other>`, since `impl Other` will begin
// to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed). // to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed).
for clause in self.tcx.item_bounds(def_id).iter_instantiated(self.tcx, opaque_ty_args) { for clause in self
.tcx
.item_bounds(def_id)
.iter_instantiated(self.tcx, opaque_ty_args)
.map(Unnormalized::skip_norm_wip)
{
clause.visit_with(self) clause.visit_with(self)
} }
} }
+3 -2
View File
@@ -141,7 +141,7 @@ fn has_unstable_into_iter_predicate<'tcx>(
} }
// `IntoIterator::into_iter` has no additional method args. // `IntoIterator::into_iter` has no additional method args.
let into_iter_fn_args = let into_iter_fn_args =
cx.tcx.instantiate_bound_regions_with_erased(trait_pred).trait_ref.args; cx.tcx.instantiate_bound_regions_with_erased(trait_pred.skip_norm_wip()).trait_ref.args;
let Ok(Some(instance)) = ty::Instance::try_resolve( let Ok(Some(instance)) = ty::Instance::try_resolve(
cx.tcx, cx.tcx,
cx.typing_env(), cx.typing_env(),
@@ -292,7 +292,8 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &hir::Path<'_>) -> Option<String
} }
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait. // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() if let ty::Adt(adt, args) =
cx.tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
&& let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) && let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
{ {
return Some(format!("{}<{}>", name, args[0])); return Some(format!("{}<{}>", name, args[0]));
@@ -1,4 +1,5 @@
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::Unnormalized;
use rustc_session::{declare_lint, declare_lint_pass}; use rustc_session::{declare_lint, declare_lint_pass};
use crate::{LateContext, LateLintPass, LintContext}; use crate::{LateContext, LateLintPass, LintContext};
@@ -46,6 +47,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
.tcx .tcx
.explicit_super_predicates_of(def_id) .explicit_super_predicates_of(def_id)
.iter_identity_copied() .iter_identity_copied()
.map(Unnormalized::skip_norm_wip)
.filter_map(|(pred, _)| pred.as_trait_clause()) .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_lang_item(pred.def_id(), hir::LangItem::MetaSized))
.filter(|pred| !cx.tcx.is_default_trait(pred.def_id())); .filter(|pred| !cx.tcx.is_default_trait(pred.def_id()));
+5 -3
View File
@@ -1,6 +1,7 @@
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_middle::ty; use rustc_middle::ty;
use rustc_middle::ty::Unnormalized;
use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind}; use rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};
use rustc_session::{declare_lint, declare_lint_pass}; use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym; use rustc_span::sym;
@@ -92,9 +93,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
return; return;
}; };
let args = cx let args = cx.tcx.normalize_erasing_regions(
.tcx cx.typing_env(),
.normalize_erasing_regions(cx.typing_env(), cx.typeck_results().node_args(expr.hir_id)); Unnormalized::new_wip(cx.typeck_results().node_args(expr.hir_id)),
);
// Resolve the trait method instance. // Resolve the trait method instance.
let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else { let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.typing_env(), did, args) else {
return; return;
@@ -2,7 +2,7 @@
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath}; 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_session::{declare_lint, declare_lint_pass};
use rustc_span::{Span, kw}; use rustc_span::{Span, kw};
use rustc_trait_selection::traits::{self, ObligationCtxt}; use rustc_trait_selection::traits::{self, ObligationCtxt};
@@ -88,7 +88,12 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>
// For every projection predicate in the opaque type's explicit bounds, // For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds // check that the type that we're assigning actually satisfies the bounds
// of the associated type. // of the associated type.
for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).iter_identity_copied() { for (pred, pred_span) in cx
.tcx
.explicit_item_bounds(def_id)
.iter_identity_copied()
.map(Unnormalized::skip_norm_wip)
{
infcx.enter_forall(pred.kind(), |predicate| { infcx.enter_forall(pred.kind(), |predicate| {
let ty::ClauseKind::Projection(proj) = predicate else { let ty::ClauseKind::Projection(proj) = predicate else {
return; return;
@@ -146,12 +151,16 @@ fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'tcx, AmbigArg>
.tcx .tcx
.explicit_item_bounds(proj.projection_term.def_id) .explicit_item_bounds(proj.projection_term.def_id)
.iter_instantiated_copied(cx.tcx, proj.projection_term.args) .iter_instantiated_copied(cx.tcx, proj.projection_term.args)
.map(Unnormalized::skip_norm_wip)
{ {
let assoc_pred = assoc_pred.fold_with(proj_replacer); let assoc_pred = assoc_pred.fold_with(proj_replacer);
let ocx = ObligationCtxt::new(infcx); let ocx = ObligationCtxt::new(infcx);
let assoc_pred = let assoc_pred = ocx.normalize(
ocx.normalize(&traits::ObligationCause::dummy(), cx.param_env, assoc_pred); &traits::ObligationCause::dummy(),
cx.param_env,
Unnormalized::new_wip(assoc_pred),
);
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
// Can't normalize for some reason...? // Can't normalize for some reason...?
continue; continue;

Some files were not shown because too many files have changed in this diff Show More