Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8005608
introduce `AliasTyKind::Ambiguous`
adwinwhite May 11, 2026
3ad3a86
folders to create and consume ambiguous
adwinwhite May 7, 2026
a5bfa85
add new wrapper def
adwinwhite May 13, 2026
d493c2a
add method to normalize ambiguous aliases outside of next solver
adwinwhite May 8, 2026
29edde4
add normalization methods to eval_ctxt
adwinwhite Apr 30, 2026
e911fbd
make instantitation renormalize
adwinwhite May 8, 2026
fdf44a2
renormalize inside solver relating
adwinwhite May 13, 2026
aaea957
make folders generic over error
adwinwhite May 13, 2026
2e93e44
revert and fix `opt_alias_variances`
adwinwhite May 13, 2026
cca7517
address some reviews
adwinwhite May 13, 2026
5f0356f
fix rustdoc and clippy
adwinwhite May 13, 2026
bda52cf
create a wrapper for fully normalization after instantiation
adwinwhite May 13, 2026
a99a408
review
lcnr May 13, 2026
8c8b131
update
lcnr May 13, 2026
6efa247
rarw
lcnr May 13, 2026
13d4544
normalize some ambiguous aliases to infer
adwinwhite May 14, 2026
e68a829
bless tests
lcnr May 13, 2026
0f6dab6
add some comments
adwinwhite May 14, 2026
f2f6adf
debugging jank
lcnr May 13, 2026
8e5bae3
the coolest bean
lcnr May 14, 2026
4cc3661
fix normalization
lcnr May 14, 2026
ddccba7
fix bootstrap with new solver
lcnr May 14, 2026
9112e1a
woops, fmt and random jank
lcnr May 14, 2026
65f4378
fmt and fix ambiguity
lcnr May 14, 2026
1a6d5ad
cool!
lcnr May 14, 2026
335882a
w
lcnr May 14, 2026
d39b14f
w
lcnr May 14, 2026
976f639
w
lcnr May 14, 2026
8ad4d27
w
lcnr May 14, 2026
1f33cf6
w
lcnr May 14, 2026
d570638
cool stuff
lcnr May 14, 2026
31fba6b
w
lcnr May 14, 2026
4f21dad
w
lcnr May 14, 2026
0e87d5d
w
lcnr May 14, 2026
2ca555a
w
lcnr May 14, 2026
2716b24
flags
lcnr May 14, 2026
00a7148
fix adt_const_params normalization
lcnr May 14, 2026
bb74aed
coolio
lcnr May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1082,7 +1082,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let typeck_results = tcx.typeck(self.mir_def_id());

// We don't use `ty.peel_refs()` to get the number of `*`s needed to get the root type.
let liberated_sig = tcx.liberate_late_bound_regions(closure_def_id.to_def_id(), args.sig());
let liberated_sig = tcx
.liberate_late_bound_regions(
closure_def_id.to_def_id(),
ty::Unnormalized::new_wip(args.sig()),
)
.skip_norm_wip();
let mut peeled_ty = liberated_sig.output();
let mut count = 0;
while let ty::Ref(_, ref_ty, _) = *peeled_ty.kind() {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,9 @@ 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().skip_norm_wip();
let liberated_sig = tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig);
let parent_fn_sig = tcx.fn_sig(parent_def_id).instantiate_identity();
let liberated_sig =
tcx.liberate_late_bound_regions(parent_def_id, parent_fn_sig).skip_norm_wip();
let parent_param_ty = *liberated_sig.inputs().get(param_index)?;

// Get the upvar's NLL type (with ReVar regions from renumbering).
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ use rustc_index::bit_set::MixedBitSet;
use rustc_index::{IndexSlice, IndexVec};
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::{
InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin,
TyCtxtInferExt,
};
use rustc_middle::mir::*;
use rustc_middle::query::Providers;
Expand Down Expand Up @@ -707,6 +708,20 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {

next_region
}

/// We expect all aliases to already be fully normalized during borrowck,
/// so we can redefine this method to just unwrap the unnormalized alias binder.
pub(crate) fn instantiate_binder_with_fresh_vars<T>(
&self,
span: Span,
lbrct: BoundRegionConversionTime,
value: ty::Binder<'tcx, T>,
) -> T
where
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{
self.infcx.instantiate_binder_with_fresh_vars(span, lbrct, value).no_ambiguous_aliases()
}
}

impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
region_ctxt_fn,
)
});
let unnormalized_sig = unnormalized_sig.no_ambiguous_aliases();
debug!(?unnormalized_sig);
// IMPORTANT: We have to prove well formed for the function signature before
// we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
{
let value = if let Some(inner) = binder.no_bound_vars() {
inner
ty::UnnormalizedAmbiguous::dummy(inner)
} else {
let infcx = self.type_checker.infcx;
let mut lazy_universe = None;
Expand Down Expand Up @@ -207,7 +207,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
};

debug!(?value);
f(self, value)
f(self, value.no_ambiguous_aliases())
}

#[instrument(skip(self), level = "debug")]
Expand Down Expand Up @@ -245,7 +245,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
let replaced = infcx.tcx.replace_bound_vars_uncached(binder, delegate);
debug!(?replaced);

replaced
replaced.no_ambiguous_aliases()
}

fn create_next_universe(&mut self) -> ty::UniverseIndex {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), kind);
ty::Region::new_var(self.tcx, indices.to_region_vid(liberated_region))
});
value
value.no_ambiguous_aliases()
}
}

Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,15 @@ pub fn validate_trivial_unsize<'tcx>(
tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized());
let universe = infcx.universe();
let ocx = ObligationCtxt::new(&infcx);
infcx.enter_forall(hr_target_principal, |target_principal| {
let source_principal = infcx.instantiate_binder_with_fresh_vars(
DUMMY_SP,
let cause = ObligationCause::dummy();
ocx.enter_forall(&cause, param_env, hr_target_principal, |target_principal| {
let source_principal = ocx.instantiate_binder_with_fresh_vars(
&cause,
BoundRegionConversionTime::HigherRankedType,
param_env,
hr_source_principal,
);
let Ok(()) = ocx.eq(
&ObligationCause::dummy(),
param_env,
target_principal,
source_principal,
) else {
let Ok(()) = ocx.eq(&cause, param_env, target_principal, source_principal) else {
return false;
};
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> {
| ty::UnsafeBinder(_) => self.pretty_print_type(ty),

// Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Error(_) => {
write!(self, "_")?;
Ok(())
}
Expand All @@ -63,13 +63,12 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> {
| ty::Coroutine(def_id, args) => self.print_def_path(def_id, args),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),

ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => {
bug!("type_name: unexpected free alias")
}
ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => {
bug!("type_name: unexpected inherent projection")
}
ty::CoroutineWitness(..) => bug!("type_name: unexpected `CoroutineWitness`"),
ty::Infer(_)
| ty::Alias(ty::AliasTy {
kind: ty::Free { .. } | ty::Inherent { .. } | ty::Ambiguous,
..
})
| ty::CoroutineWitness(..) => bug!("type_name: unexpected type: {ty:?}"),
}
}

Expand Down
27 changes: 12 additions & 15 deletions compiler/rustc_hir_analysis/src/check/compare_eii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,22 @@ pub(crate) fn compare_eii_function_types<'tcx>(
let mut wf_tys = FxIndexSet::default();
let norm_cause = ObligationCause::misc(external_impl_span, external_impl);

let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity().skip_norm_wip();
let declaration_sig = tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig);
let declaration_sig = tcx.fn_sig(foreign_item).instantiate_identity();
let declaration_sig =
tcx.liberate_late_bound_regions(external_impl.into(), declaration_sig).skip_norm_wip();
debug!(?declaration_sig);

let unnormalized_external_impl_sig = infcx.instantiate_binder_with_fresh_vars(
// We need to check wf of the unnormalized sig.
let unnormalized_external_impl_sig = infcx.instantiate_unnormalized_binder_with_fresh_vars(
external_impl_span,
infer::BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(external_impl)
.instantiate(
tcx,
infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()),
)
.skip_norm_wip(),
);
let external_impl_sig = ocx.normalize(
&norm_cause,
param_env,
Unnormalized::new_wip(unnormalized_external_impl_sig),
tcx.fn_sig(external_impl).instantiate(
tcx,
infcx.fresh_args_for_item(external_impl_span, external_impl.to_def_id()),
),
);
let external_impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_external_impl_sig);

debug!(?external_impl_sig);

// Next, add all inputs and output as well-formed tys. Importantly,
Expand Down Expand Up @@ -125,7 +122,7 @@ pub(crate) fn compare_eii_function_types<'tcx>(
}

if !(declaration_sig, external_impl_sig).references_error() {
for ty in unnormalized_external_impl_sig.inputs_and_output {
for ty in unnormalized_external_impl_sig.skip_normalization().inputs_and_output {
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause.clone(),
Expand Down
44 changes: 22 additions & 22 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,20 @@ fn compare_method_predicate_entailment<'tcx>(

let mut wf_tys = FxIndexSet::default();

let unnormalized_impl_sig = infcx.instantiate_binder_with_fresh_vars(
// We need to check wf of unnormalized sig.
let unnormalized_impl_sig = infcx.instantiate_unnormalized_binder_with_fresh_vars(
impl_m_span,
BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(),
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
);

let norm_cause = ObligationCause::misc(impl_m_span, impl_m_def_id);
let impl_sig =
ocx.normalize(&norm_cause, param_env, Unnormalized::new_wip(unnormalized_impl_sig));
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);

debug!(?impl_sig);

let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip();
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
let trait_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig).skip_norm_wip();

// Next, add all inputs and output as well-formed tys. Importantly,
// we have to do this before normalization, since the normalized ty may
Expand Down Expand Up @@ -375,7 +376,7 @@ fn compare_method_predicate_entailment<'tcx>(
}

if !(impl_sig, trait_sig).references_error() {
for ty in unnormalized_impl_sig.inputs_and_output {
for ty in unnormalized_impl_sig.skip_normalization().inputs_and_output {
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause.clone(),
Expand Down Expand Up @@ -534,15 +535,12 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(

// Normalize the impl signature with fresh variables for lifetime inference.
let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
let impl_sig = ocx.normalize(
&misc_cause,
param_env,
Unnormalized::new_wip(infcx.instantiate_binder_with_fresh_vars(
return_span,
BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity().skip_norm_wip(),
)),
let impl_sig = infcx.instantiate_unnormalized_binder_with_fresh_vars(
return_span,
BoundRegionConversionTime::HigherRankedType,
tcx.fn_sig(impl_m.def_id).instantiate_identity(),
);
let impl_sig = ocx.normalize(&misc_cause, param_env, impl_sig);
impl_sig.error_reported()?;
let impl_return_ty = impl_sig.output();

Expand All @@ -554,8 +552,9 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let unnormalized_trait_sig = tcx
.liberate_late_bound_regions(
impl_m.def_id,
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args).skip_norm_wip(),
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_to_impl_args),
)
.skip_norm_wip()
.fold_with(&mut collector);

let trait_sig =
Expand Down Expand Up @@ -1259,12 +1258,12 @@ fn check_region_late_boundedness<'tcx>(
.build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id));

let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id);
let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args).skip_norm_wip();
let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig);
let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args);
let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig).skip_norm_wip();

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).skip_norm_wip();
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig);
let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args);
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig).skip_norm_wip();

let ocx = ObligationCtxt::new(&infcx);

Expand Down Expand Up @@ -1515,11 +1514,12 @@ fn compare_self_type<'tcx>(
}
ty::AssocContainer::Trait => tcx.types.self_param,
};
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip().input(0);
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().map(|sig| sig.input(0));
let (infcx, param_env) = tcx
.infer_ctxt()
.build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, method.def_id));
let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
let self_arg_ty =
tcx.liberate_late_bound_regions(method.def_id, self_arg_ty).skip_norm_wip();
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty);
get_self_string(self_arg_ty, can_eq_self)
};
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,23 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
let impl_def_id = impl_m.container_id(tcx);
let impl_m_args = ty::GenericArgs::identity_for_item(tcx, impl_m.def_id);
let trait_m_to_impl_m_args = impl_m_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args);
let bound_trait_m_sig =
tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args).skip_norm_wip();
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, bound_trait_m_sig);
let bound_trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args);
let trait_m_sig =
tcx.liberate_late_bound_regions(impl_m.def_id, bound_trait_m_sig).skip_norm_wip();
// replace the self type of the trait ref with `Self` so that diagnostics render better.
let trait_m_sig_with_self_for_diag = tcx.liberate_late_bound_regions(
impl_m.def_id,
tcx.fn_sig(trait_m.def_id)
.instantiate(
let trait_m_sig_with_self_for_diag = tcx
.liberate_late_bound_regions(
impl_m.def_id,
tcx.fn_sig(trait_m.def_id).instantiate(
tcx,
tcx.mk_args_from_iter(
[tcx.types.self_param.into()]
.into_iter()
.chain(trait_m_to_impl_m_args.iter().skip(1)),
),
)
.skip_norm_wip(),
);
),
)
.skip_norm_wip();

let Ok(hidden_tys) = tcx.collect_return_position_impl_trait_in_trait_tys(impl_m.def_id) else {
// Error already emitted, no need to delay another.
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,9 @@ fn suggestion_signature<'tcx>(
tcx,
tcx.liberate_late_bound_regions(
assoc.def_id,
tcx.fn_sig(assoc.def_id).instantiate(tcx, args).skip_norm_wip(),
),
tcx.fn_sig(assoc.def_id).instantiate(tcx, args),
)
.skip_norm_wip(),
assoc.ident(tcx),
tcx.predicates_of(assoc.def_id)
.instantiate_own(tcx, args)
Expand Down
Loading
Loading