Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_infer::traits::query::{
};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex,
self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, Unnormalized,
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
Expand Down Expand Up @@ -275,7 +275,7 @@ where
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
// test. Check after #85499 lands to see if its fixes have erased this difference.
let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.normalize(&cause, param_env, value.value);
let _ = ocx.normalize(&cause, param_env, Unnormalized::new_wip(value.value));

let diag = try_extract_error_from_fulfill_cx(
&ocx,
Expand Down Expand Up @@ -322,7 +322,7 @@ where
let ocx = ObligationCtxt::new(&infcx);

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

let diag = try_extract_error_from_fulfill_cx(
&ocx,
Expand Down
29 changes: 19 additions & 10 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,19 +754,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}

// Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
clauses.instantiate(tcx, new_args).predicates.iter().all(|clause| {
// Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = tcx.try_normalize_erasing_regions(
self.infcx.typing_env(self.infcx.param_env),
clause,
) {
clause = normalized;
}
let normalized = tcx
.try_normalize_erasing_regions(
self.infcx.typing_env(self.infcx.param_env),
clause.clone(),
)
.unwrap_or_else(|_| clause.skip_norm_wip());
Comment thread
lcnr marked this conversation as resolved.
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
tcx,
ObligationCause::dummy(),
self.infcx.param_env,
clause,
normalized,
))
})
}) {
Expand Down Expand Up @@ -4171,11 +4171,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if is_closure {
None
} else {
let ty = self.infcx.tcx.type_of(self.mir_def_id()).instantiate_identity();
let ty = self
.infcx
.tcx
.type_of(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip();
match ty.kind() {
ty::FnDef(_, _) | ty::FnPtr(..) => self.annotate_fn_sig(
self.mir_def_id(),
self.infcx.tcx.fn_sig(self.mir_def_id()).instantiate_identity(),
self.infcx
.tcx
.fn_sig(self.mir_def_id())
.instantiate_identity()
.skip_norm_wip(),
),
_ => None,
}
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,9 +1366,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let parent_self_ty =
matches!(tcx.def_kind(parent_did), rustc_hir::def::DefKind::Impl { .. })
.then_some(parent_did)
.and_then(|did| match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, ..) => Some(def.did()),
_ => None,
.and_then(|did| {
match tcx.type_of(did).instantiate_identity().skip_norm_wip().kind()
{
ty::Adt(def, ..) => Some(def.did()),
_ => None,
}
});
let is_option_or_result = parent_self_ty.is_some_and(|def_id| {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
Expand Down Expand Up @@ -1445,7 +1448,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span,
BoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
tcx.fn_sig(method_did)
.instantiate(tcx, method_args)
.skip_norm_wip()
.input(0),
)
&& self.infcx.can_eq(self.infcx.param_env, ty, self_ty)
{
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Check whether one of the where-bounds requires the closure to impl `Fn[Mut]`
// or `AsyncFn[Mut]`.
for (pred, span) in predicates.predicates.iter().zip(predicates.spans.iter()) {
let pred = pred.skip_norm_wip();
let dominated_by_fn_trait = self
.closure_clause_kind(*pred, def_id, asyncness)
.closure_clause_kind(pred, def_id, asyncness)
.is_some_and(|kind| matches!(kind, ty::ClosureKind::Fn | ty::ClosureKind::FnMut));
if dominated_by_fn_trait {
// Found `<TyOfCapturingClosure as FnMut>` or
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::mir::{self, ConstraintCategory, Location};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
Unnormalized,
};
use rustc_span::Span;
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
Expand Down Expand Up @@ -282,6 +283,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGen
.tcx
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, args)
.map(Unnormalized::skip_norm_wip)
{
bound.visit_with(self)?;
}
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

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

debug!("report_fnmut_error: output_ty={:?}", output_ty);
Expand Down Expand Up @@ -930,7 +930,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
debug!(?fn_did, ?args);

// Only suggest this on function calls, not closures
let ty = tcx.type_of(fn_did).instantiate_identity();
let ty = tcx.type_of(fn_did).instantiate_identity().skip_norm_wip();
debug!("ty: {:?}, ty.kind: {:?}", ty, ty.kind());
if let ty::Closure(_, _) = ty.kind() {
return;
Expand Down Expand Up @@ -1050,7 +1050,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
else {
return;
};
let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind()
let ty::Closure(_, args) =
*tcx.type_of(closure_def_id).instantiate_identity().skip_norm_wip().kind()
else {
return;
};
Expand Down Expand Up @@ -1148,7 +1149,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let ocx = ObligationCtxt::new(&self.infcx);
ocx.register_obligations(preds.iter().map(|(pred, span)| {
trace!(?pred);
Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred)
Obligation::misc(
tcx,
span,
self.mir_def_id(),
self.infcx.param_env,
pred.skip_norm_wip(),
)
}));

if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty};
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, RegionVid, Ty, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
Expand Down Expand Up @@ -418,7 +418,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {

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

Expand Down Expand Up @@ -1023,10 +1023,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
return None;
};

let found = tcx
.any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| {
r.kind() == ty::ReEarlyParam(region)
});
let found = tcx.any_free_region_meets(
&tcx.type_of(region_parent).instantiate_identity().skip_norm_wip(),
|r| r.kind() == ty::ReEarlyParam(region),
);

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

let predicates = self
let predicates: Vec<_> = self
.infcx
.tcx
.predicates_of(self.body.source.def_id())
.instantiate_identity(self.infcx.tcx)
.predicates;
.predicates
.into_iter()
.map(Unnormalized::skip_norm_wip)
.collect();

if let Some(upvar_index) = self
.regioncx
Expand Down
32 changes: 19 additions & 13 deletions compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions,
};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::Span;
Expand Down Expand Up @@ -569,16 +569,17 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
};

// We erase all non-member region of the opaque and need to treat these as existentials.
let expected_ty =
ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| {
match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
}
});
let expected_ty = ty::fold_regions(
tcx,
expected.ty.instantiate(tcx, key.args).skip_norm_wip(),
|re, _dbi| match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
},
);

// We now simply equate the expected with the actual hidden type.
let locations = Locations::All(hidden_type.span);
Expand All @@ -598,8 +599,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
body.source.def_id().expect_local(),
);
// We need to normalize both types in the old solver before equatingt them.
let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty);
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty);
let actual_ty = ocx.normalize(
&cause,
infcx.param_env,
Unnormalized::new_wip(hidden_type.ty),
);
let expected_ty =
ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty));
ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
},
"equating opaque types",
Expand Down
21 changes: 11 additions & 10 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_middle::bug;
use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Upcast};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_trait_selection::solve::NoSolution;
Expand Down Expand Up @@ -189,7 +189,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{
self.normalize_with_category(value, location, ConstraintCategory::Boring)
self.normalize_with_category(
Unnormalized::new_wip(value),
Copy link
Copy Markdown
Contributor

@lcnr lcnr Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not propagating this one out?

View changes since the review

location,
ConstraintCategory::Boring,
)
}

pub(super) fn deeply_normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
Expand All @@ -207,13 +211,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
pub(super) fn normalize_with_category<T>(
&mut self,
value: T,
value: Unnormalized<'tcx, T>,
location: impl NormalizeLocation,
category: ConstraintCategory<'tcx>,
) -> T
where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{
let value = value.inside_norm();
Copy link
Copy Markdown
Contributor

@lcnr lcnr Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let value = value.inside_norm();
let value = value.skip_norm_wip();

would want us to propagate the Unnormalized into the type op and only discard it when actually normalizing

View changes since the review

let param_env = self.infcx.param_env;
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
location.to_locations(),
Expand Down Expand Up @@ -246,11 +251,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CustomTypeOp::new(
|ocx| {
let structurally_normalize = |ty| {
ocx.structurally_normalize_ty(
&cause,
param_env,
ty,
)
ocx.structurally_normalize_ty(&cause, param_env, Unnormalized::new_wip(ty))
.unwrap_or_else(|_| bug!("struct tail should have been computable, since we computed it in HIR"))
};

Expand Down Expand Up @@ -295,7 +296,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
body.source.def_id().expect_local(),
),
param_env,
ty,
Unnormalized::new_wip(ty),
)
.map_err(|_| NoSolution)
},
Expand Down Expand Up @@ -364,7 +365,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// obligation for the unnormalized user_ty here. This is
// where the "incorrectly skips the WF checks we normally do"
// happens
let user_ty = ocx.normalize(&cause, param_env, user_ty);
let user_ty = ocx.normalize(&cause, param_env, Unnormalized::new_wip(user_ty));
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
Ok(())
},
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1759,7 +1759,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let unnormalized_ty =
tcx.type_of(static_def_id).instantiate_identity().skip_norm_wip();
let normalized_ty = self.normalize(unnormalized_ty, locations);
Comment on lines +1762 to 1764
Copy link
Copy Markdown
Contributor

@lcnr lcnr Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, want to change TypeChecker::normalize to also take Unnormalized

View changes since the review

let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();

Expand Down
Loading
Loading