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
15 changed files with 53 additions and 42 deletions
+1 -1
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 {
@@ -888,8 +888,8 @@ pub(crate) fn report_unresolved_inherent_assoc_item(
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}");
+6 -4
View File
@@ -1800,11 +1800,13 @@ fn suggest_boxing_tail_for_return_position_impl_trait(
.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()?;
@@ -1053,8 +1053,8 @@ fn report_no_match_method_error(
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 @@ fn note_candidates_on_method_error(
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 @@ fn note_candidates_on_method_error(
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,
@@ -167,7 +167,7 @@ fn update_infer_var_info(&self, obligation: &PredicateObligation<'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),
)),
),
);
@@ -50,7 +50,7 @@ pub(super) trait GoalKind<D, I = <D as SolverDelegate>::Interner>:
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 @@ pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
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);
@@ -29,8 +29,8 @@ fn trait_ref(self, _: I) -> ty::TraitRef<I> {
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 {
@@ -99,8 +99,8 @@ fn trait_ref(self, cx: I) -> ty::TraitRef<I> {
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 {
@@ -33,8 +33,8 @@ fn trait_ref(self, _: I) -> ty::TraitRef<I> {
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 @@ fn probe_and_evaluate_goal_for_constituent_tys(
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);
@@ -581,7 +581,7 @@ pub fn suggest_copy_trait_method_bounds(
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);
@@ -512,7 +512,7 @@ pub fn report_selection_error(
&& 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 @@ pub(super) fn mk_trait_obligation_with_new_self_ty(
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)
}
@@ -3942,7 +3942,7 @@ fn note_function_argument_obligation<G: EmissionGuarantee>(
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 @@ pub(super) fn suggest_tuple_wrapping(
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 =
+16 -10
View File
@@ -97,7 +97,7 @@ pub fn identity(interner: I, def_id: I::DefId) -> 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 @@ pub fn self_ty(self) -> I::Ty {
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 @@ pub fn self_ty(self) -> I::Ty {
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 @@ pub fn self_ty(self) -> I::Ty {
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 @@ pub fn self_ty(self) -> I::Ty {
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 {
+1 -1
View File
@@ -475,7 +475,7 @@ pub fn self_ty(self) -> I::Ty {
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,
@@ -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);