Auto merge of #139598 - compiler-errors:no-bound-var-symbol, r=WaffleLapkin

Remove `Symbol` from `Named` variant of `BoundRegionKind`/`LateParamRegionKind`

The `Symbol` is redundant, since we already store a `DefId` in the region variant. Instead, load the name via `item_name` when needed (which is almost always on the diagnostic path).

This introduces a `BoundRegionKind::NamedAnon` which is used for giving anonymous bound regions names, but which should only be used during pretty printing and error reporting.
This commit is contained in:
bors 2025-07-05 06:29:56 +00:00
commit f0b67dd97d
47 changed files with 377 additions and 409 deletions

View file

@ -293,7 +293,7 @@ pub(super) fn build_function(cx: &mut DocContext<'_>, def_id: DefId) -> Box<clea
let sig = cx.tcx.fn_sig(def_id).instantiate_identity();
// The generics need to be cleaned before the signature.
let mut generics = clean_ty_generics(cx, def_id);
let bound_vars = clean_bound_vars(sig.bound_vars());
let bound_vars = clean_bound_vars(sig.bound_vars(), cx);
// At the time of writing early & late-bound params are stored separately in rustc,
// namely in `generics.params` and `bound_vars` respectively.

View file

@ -273,7 +273,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>(
GenericBound::TraitBound(
PolyTrait {
trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
generic_params: clean_bound_vars(poly_trait_ref.bound_vars()),
generic_params: clean_bound_vars(poly_trait_ref.bound_vars(), cx),
},
hir::TraitBoundModifiers::NONE,
)
@ -325,24 +325,11 @@ pub(crate) fn clean_middle_const<'tcx>(
ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() }
}
pub(crate) fn clean_middle_region(region: ty::Region<'_>) -> Option<Lifetime> {
match region.kind() {
ty::ReStatic => Some(Lifetime::statik()),
_ if !region.has_name() => None,
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
Some(Lifetime(name))
}
ty::ReEarlyParam(ref data) => Some(Lifetime(data.name)),
ty::ReBound(..)
| ty::ReLateParam(..)
| ty::ReVar(..)
| ty::ReError(_)
| ty::RePlaceholder(..)
| ty::ReErased => {
debug!("cannot clean region {region:?}");
None
}
}
pub(crate) fn clean_middle_region<'tcx>(
region: ty::Region<'tcx>,
cx: &mut DocContext<'tcx>,
) -> Option<Lifetime> {
region.get_name(cx.tcx).map(Lifetime)
}
fn clean_where_predicate<'tcx>(
@ -384,7 +371,7 @@ pub(crate) fn clean_predicate<'tcx>(
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx),
ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred)),
ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred, cx)),
ty::ClauseKind::TypeOutlives(pred) => {
Some(clean_type_outlives_predicate(bound_predicate.rebind(pred), cx))
}
@ -418,13 +405,16 @@ fn clean_poly_trait_predicate<'tcx>(
})
}
fn clean_region_outlives_predicate(pred: ty::RegionOutlivesPredicate<'_>) -> WherePredicate {
fn clean_region_outlives_predicate<'tcx>(
pred: ty::RegionOutlivesPredicate<'tcx>,
cx: &mut DocContext<'tcx>,
) -> WherePredicate {
let ty::OutlivesPredicate(a, b) = pred;
WherePredicate::RegionPredicate {
lifetime: clean_middle_region(a).expect("failed to clean lifetime"),
lifetime: clean_middle_region(a, cx).expect("failed to clean lifetime"),
bounds: vec![GenericBound::Outlives(
clean_middle_region(b).expect("failed to clean bounds"),
clean_middle_region(b, cx).expect("failed to clean bounds"),
)],
}
}
@ -438,7 +428,7 @@ fn clean_type_outlives_predicate<'tcx>(
WherePredicate::BoundPredicate {
ty: clean_middle_ty(pred.rebind(ty), cx, None, None),
bounds: vec![GenericBound::Outlives(
clean_middle_region(lt).expect("failed to clean lifetimes"),
clean_middle_region(lt, cx).expect("failed to clean lifetimes"),
)],
bound_params: Vec::new(),
}
@ -1905,8 +1895,8 @@ fn clean_trait_object_lifetime_bound<'tcx>(
match region.kind() {
ty::ReStatic => Some(Lifetime::statik()),
ty::ReEarlyParam(region) => Some(Lifetime(region.name)),
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => {
Some(Lifetime(name))
ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(def_id), .. }) => {
Some(Lifetime(tcx.item_name(def_id)))
}
ty::ReBound(..)
| ty::ReLateParam(_)
@ -1935,7 +1925,9 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
match default {
ObjectLifetimeDefault::Static => return region.kind() == ty::ReStatic,
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
ObjectLifetimeDefault::Arg(default) => return region.get_name() == default.get_name(),
ObjectLifetimeDefault::Arg(default) => {
return region.get_name(tcx) == default.get_name(tcx);
}
// > If there is more than one bound from the containing type then an explicit bound must be specified
// Due to ambiguity there is no default trait-object lifetime and thus elision is impossible.
// Don't elide the lifetime.
@ -1957,7 +1949,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
// > If the trait is defined with a single lifetime bound then that bound is used.
// > If 'static is used for any lifetime bound then 'static is used.
// FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly.
[object_region] => object_region.get_name() == region.get_name(),
[object_region] => object_region.get_name(tcx) == region.get_name(tcx),
// There are several distinct trait regions and none are `'static`.
// Due to ambiguity there is no default trait-object lifetime and thus elision is impossible.
// Don't elide the lifetime.
@ -2051,7 +2043,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
RawPointer(mutbl, Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)))
}
ty::Ref(r, ty, mutbl) => BorrowedRef {
lifetime: clean_middle_region(r),
lifetime: clean_middle_region(r, cx),
mutability: mutbl,
type_: Box::new(clean_middle_ty(
bound_ty.rebind(ty),
@ -2064,7 +2056,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
// FIXME: should we merge the outer and inner binders somehow?
let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
let decl = clean_poly_fn_sig(cx, None, sig);
let generic_params = clean_bound_vars(sig.bound_vars());
let generic_params = clean_bound_vars(sig.bound_vars(), cx);
BareFunction(Box::new(BareFunctionDecl {
safety: sig.safety(),
@ -2074,7 +2066,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
}))
}
ty::UnsafeBinder(inner) => {
let generic_params = clean_bound_vars(inner.bound_vars());
let generic_params = clean_bound_vars(inner.bound_vars(), cx);
let ty = clean_middle_ty(inner.into(), cx, None, None);
UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, ty }))
}
@ -2148,10 +2140,13 @@ pub(crate) fn clean_middle_ty<'tcx>(
.iter()
.flat_map(|pred| pred.bound_vars())
.filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BoundRegionKind::Named(def_id, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(def_id, name))
ty::BoundVariableKind::Region(ty::BoundRegionKind::Named(def_id)) => {
let name = cx.tcx.item_name(def_id);
if name != kw::UnderscoreLifetime {
Some(GenericParamDef::lifetime(def_id, name))
} else {
None
}
}
_ => None,
})
@ -2226,7 +2221,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
}
ty::Bound(_, ref ty) => match ty.kind {
ty::BoundTyKind::Param(_, name) => Generic(name),
ty::BoundTyKind::Param(def_id) => Generic(cx.tcx.item_name(def_id)),
ty::BoundTyKind::Anon => panic!("unexpected anonymous bound type variable"),
},
@ -2282,7 +2277,7 @@ fn clean_middle_opaque_bounds<'tcx>(
let trait_ref = match bound_predicate.skip_binder() {
ty::ClauseKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref),
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
return clean_middle_region(reg).map(GenericBound::Outlives);
return clean_middle_region(reg, cx).map(GenericBound::Outlives);
}
_ => return None,
};
@ -3182,16 +3177,23 @@ fn clean_assoc_item_constraint<'tcx>(
}
}
fn clean_bound_vars(bound_vars: &ty::List<ty::BoundVariableKind>) -> Vec<GenericParamDef> {
fn clean_bound_vars<'tcx>(
bound_vars: &ty::List<ty::BoundVariableKind>,
cx: &mut DocContext<'tcx>,
) -> Vec<GenericParamDef> {
bound_vars
.into_iter()
.filter_map(|var| match var {
ty::BoundVariableKind::Region(ty::BoundRegionKind::Named(def_id, name))
if name != kw::UnderscoreLifetime =>
{
Some(GenericParamDef::lifetime(def_id, name))
ty::BoundVariableKind::Region(ty::BoundRegionKind::Named(def_id)) => {
let name = cx.tcx.item_name(def_id);
if name != kw::UnderscoreLifetime {
Some(GenericParamDef::lifetime(def_id, name))
} else {
None
}
}
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, name)) => {
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id)) => {
let name = cx.tcx.item_name(def_id);
Some(GenericParamDef {
name,
def_id,

View file

@ -125,9 +125,9 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
}
match arg.skip_binder().kind() {
GenericArgKind::Lifetime(lt) => {
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
}
GenericArgKind::Lifetime(lt) => Some(GenericArg::Lifetime(
clean_middle_region(lt, cx).unwrap_or(Lifetime::elided()),
)),
GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty(
arg.rebind(ty),
cx,