Rollup merge of #144694 - compiler-errors:with-self-ty, r=SparrowLii

Distinguish prepending and replacing self ty in predicates

There are two kinds of functions called `with_self_ty`:
1. Prepends the `Self` type onto an `ExistentialPredicate` which lacks it in its internal representation.
2. Replaces the `Self` type of an existing predicate, either for diagnostics purposes or in the new trait solver when normalizing that self type.

This PR distinguishes these two because I often want to only grep for one of them. Namely, let's call it `with_replaced_self_ty` when all we're doing is replacing the self type.
This commit is contained in:
Stuart Cook 2025-08-04 14:58:09 +10:00 committed by GitHub
commit 7307dc0ca1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 53 additions and 42 deletions

View file

@ -493,7 +493,7 @@ fn suggestion_signature<'tcx>(
let args = ty::GenericArgs::identity_for_item(tcx, assoc.def_id).rebase_onto(
tcx,
assoc.container_id(tcx),
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).args,
impl_trait_ref.with_replaced_self_ty(tcx, tcx.types.self_param).args,
);
match assoc.kind {

View file

@ -888,8 +888,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
// `<Foo as Iterator>::Item = String`.
let projection_term = pred.projection_term;
let quiet_projection_term =
projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
let quiet_projection_term = projection_term
.with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
let term = pred.term;
let obligation = format!("{projection_term} = {term}");

View file

@ -1800,11 +1800,13 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
.kind()
.map_bound(|clause| match clause {
ty::ClauseKind::Trait(trait_pred) => Some(ty::ClauseKind::Trait(
trait_pred.with_self_ty(fcx.tcx, ty),
trait_pred.with_replaced_self_ty(fcx.tcx, ty),
)),
ty::ClauseKind::Projection(proj_pred) => Some(
ty::ClauseKind::Projection(proj_pred.with_self_ty(fcx.tcx, ty)),
),
ty::ClauseKind::Projection(proj_pred) => {
Some(ty::ClauseKind::Projection(
proj_pred.with_replaced_self_ty(fcx.tcx, ty),
))
}
_ => None,
})
.transpose()?;

View file

@ -1053,8 +1053,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let pred = bound_predicate.rebind(pred);
// `<Foo as Iterator>::Item = String`.
let projection_term = pred.skip_binder().projection_term;
let quiet_projection_term =
projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
let quiet_projection_term = projection_term
.with_replaced_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO));
let term = pred.skip_binder().term;
@ -2157,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx,
self.fresh_args_for_item(sugg_span, impl_did),
)
.with_self_ty(self.tcx, rcvr_ty),
.with_replaced_self_ty(self.tcx, rcvr_ty),
idx,
sugg_span,
item,
@ -2196,7 +2196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
trait_did,
self.fresh_args_for_item(sugg_span, trait_did),
)
.with_self_ty(self.tcx, rcvr_ty),
.with_replaced_self_ty(self.tcx, rcvr_ty),
idx,
sugg_span,
item,

View file

@ -167,7 +167,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
obligation.predicate.kind().rebind(
// (*) binder moved here
ty::PredicateKind::Clause(ty::ClauseKind::Trait(
tpred.with_self_ty(self.tcx, new_self_ty),
tpred.with_replaced_self_ty(self.tcx, new_self_ty),
)),
),
);

View file

@ -50,7 +50,7 @@ where
fn trait_ref(self, cx: I) -> ty::TraitRef<I>;
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
fn trait_def_id(self, cx: I) -> I::DefId;
@ -376,8 +376,8 @@ where
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
}
let goal: Goal<I, G> =
goal.with(self.cx(), goal.predicate.with_self_ty(self.cx(), normalized_self_ty));
let goal: Goal<I, G> = goal
.with(self.cx(), goal.predicate.with_replaced_self_ty(self.cx(), normalized_self_ty));
// Vars that show up in the rest of the goal substs may have been constrained by
// normalizing the self type as well, since type variables are not uniquified.
let goal = self.resolve_vars_if_possible(goal);

View file

@ -29,8 +29,8 @@ where
self.trait_ref
}
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_self_ty(cx, self_ty)
fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, _: I) -> I::DefId {

View file

@ -99,8 +99,8 @@ where
self.alias.trait_ref(cx)
}
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_self_ty(cx, self_ty)
fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, cx: I) -> I::DefId {

View file

@ -33,8 +33,8 @@ where
self.trait_ref
}
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_self_ty(cx, self_ty)
fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, _: I) -> I::DefId {
@ -1263,7 +1263,9 @@ where
let goals =
ecx.enter_forall(constituent_tys(ecx, goal.predicate.self_ty())?, |ecx, tys| {
tys.into_iter()
.map(|ty| goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty)))
.map(|ty| {
goal.with(ecx.cx(), goal.predicate.with_replaced_self_ty(ecx.cx(), ty))
})
.collect::<Vec<_>>()
});
ecx.add_goals(GoalSource::ImplWhereBound, goals);

View file

@ -581,7 +581,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let trait_args = trait_ref
.instantiate_identity()
// Replace the explicit self type with `Self` for better suggestion rendering
.with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
.with_replaced_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper))
.args;
let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id)
.rebase_onto(self.tcx, impl_def_id, trait_args);

View file

@ -512,7 +512,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&& self.fallback_has_occurred
{
let predicate = leaf_trait_predicate.map_bound(|trait_pred| {
trait_pred.with_self_ty(self.tcx, tcx.types.unit)
trait_pred.with_replaced_self_ty(self.tcx, tcx.types.unit)
});
let unit_obligation = obligation.with(tcx, predicate);
if self.predicate_may_hold(&unit_obligation) {
@ -2364,8 +2364,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
param_env: ty::ParamEnv<'tcx>,
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
) -> PredicateObligation<'tcx> {
let trait_pred =
trait_ref_and_ty.map_bound(|(tr, new_self_ty)| tr.with_self_ty(self.tcx, new_self_ty));
let trait_pred = trait_ref_and_ty
.map_bound(|(tr, new_self_ty)| tr.with_replaced_self_ty(self.tcx, new_self_ty));
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
}

View file

@ -3942,7 +3942,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let hir::Expr { kind: hir::ExprKind::MethodCall(_, rcvr, _, _), .. } = expr
&& let Some(ty) = typeck_results.node_type_opt(rcvr.hir_id)
&& let Some(failed_pred) = failed_pred.as_trait_clause()
&& let pred = failed_pred.map_bound(|pred| pred.with_self_ty(tcx, ty))
&& let pred = failed_pred.map_bound(|pred| pred.with_replaced_self_ty(tcx, ty))
&& self.predicate_must_hold_modulo_regions(&Obligation::misc(
tcx, expr.span, body_id, param_env, pred,
))
@ -4624,9 +4624,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let Some(root_pred) = root_obligation.predicate.as_trait_clause() else { return };
let trait_ref = root_pred.map_bound(|root_pred| {
root_pred
.trait_ref
.with_self_ty(self.tcx, Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]))
root_pred.trait_ref.with_replaced_self_ty(
self.tcx,
Ty::new_tup(self.tcx, &[root_pred.trait_ref.self_ty()]),
)
});
let obligation =

View file

@ -97,7 +97,7 @@ impl<I: Interner> TraitRef<I> {
)
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
TraitRef::new(
interner,
self.def_id,
@ -146,8 +146,11 @@ pub struct TraitPredicate<I: Interner> {
}
impl<I: Interner> TraitPredicate<I> {
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity }
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
Self {
trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty),
polarity: self.polarity,
}
}
pub fn def_id(self) -> I::DefId {
@ -645,7 +648,7 @@ impl<I: Interner> AliasTerm<I> {
self.args.type_at(0)
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
AliasTerm::new(
interner,
self.def_id,
@ -756,8 +759,11 @@ impl<I: Interner> ProjectionPredicate<I> {
self.projection_term.self_ty()
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
Self {
projection_term: self.projection_term.with_replaced_self_ty(interner, self_ty),
..self
}
}
pub fn trait_def_id(self, interner: I) -> I::DefId {
@ -814,8 +820,8 @@ impl<I: Interner> NormalizesTo<I> {
self.alias.self_ty()
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
}
pub fn trait_def_id(self, interner: I) -> I::DefId {
@ -849,8 +855,8 @@ impl<I: Interner> HostEffectPredicate<I> {
self.trait_ref.self_ty()
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
}
pub fn def_id(self) -> I::DefId {

View file

@ -475,7 +475,7 @@ impl<I: Interner> AliasTy<I> {
self.args.type_at(0)
}
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
pub fn with_replaced_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
AliasTy::new(
interner,
self.def_id,

View file

@ -417,7 +417,7 @@ fn replace_types<'tcx>(
{
let projection = projection_predicate
.projection_term
.with_self_ty(cx.tcx, new_ty)
.with_replaced_self_ty(cx.tcx, new_ty)
.expect_ty(cx.tcx)
.to_ty(cx.tcx);