diff options
Diffstat (limited to 'src/librustdoc/clean/mod.rs')
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0182d50773d..8ad1ed09597 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -167,8 +167,7 @@ fn clean_generic_bound<'tcx>( let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id)); let generic_args = clean_generic_args(generic_args, cx); - let GenericArgs::AngleBracketed { bindings, .. } = generic_args - else { + let GenericArgs::AngleBracketed { bindings, .. } = generic_args else { bug!("clean: parenthesized `GenericBound::LangItemTrait`"); }; @@ -1818,33 +1817,46 @@ fn can_elide_trait_object_lifetime_bound<'tcx>( #[derive(Debug)] pub(crate) enum ContainerTy<'tcx> { Ref(ty::Region<'tcx>), - Regular { ty: DefId, substs: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize }, + Regular { + ty: DefId, + args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, + has_self: bool, + arg: usize, + }, } impl<'tcx> ContainerTy<'tcx> { fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> { match self { Self::Ref(region) => ObjectLifetimeDefault::Arg(region), - Self::Regular { ty: container, substs, arg: index } => { + Self::Regular { ty: container, args, has_self, arg: index } => { let (DefKind::Struct | DefKind::Union | DefKind::Enum - | DefKind::TyAlias - | DefKind::Trait - | DefKind::AssocTy - | DefKind::Variant) = tcx.def_kind(container) + | DefKind::TyAlias { .. } + | DefKind::Trait) = tcx.def_kind(container) else { return ObjectLifetimeDefault::Empty; }; let generics = tcx.generics_of(container); - let param = generics.params[index].def_id; - let default = tcx.object_lifetime_default(param); + debug_assert_eq!(generics.parent_count, 0); + + // If the container is a trait object type, the arguments won't contain the self type but the + // generics of the corresponding trait will. In such a case, offset the index by one. + // For comparison, if the container is a trait inside a bound, the arguments do contain the + // self type. + let offset = + if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 }; + let param = generics.params[index + offset].def_id; + let default = tcx.object_lifetime_default(param); match default { rbv::ObjectLifetimeDefault::Param(lifetime) => { + // The index is relative to the parent generics but since we don't have any, + // we don't need to translate it. let index = generics.param_def_id_to_index[&lifetime]; - let arg = substs.skip_binder()[index as usize].expect_region(); + let arg = args.skip_binder()[index as usize].expect_region(); ObjectLifetimeDefault::Arg(arg) } rbv::ObjectLifetimeDefault::Empty => ObjectLifetimeDefault::Empty, |
