Auto merge of #115276 - fmease:rustdoc-obj-lt-defs-handle-self-ty-params, r=GuillaumeGomez
rustdoc: correctly deal with self ty params when eliding default object lifetimes Fixes #115179.
This commit is contained in:
commit
35e416303e
@ -1959,31 +1959,44 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum ContainerTy<'tcx> {
|
pub(crate) enum ContainerTy<'tcx> {
|
||||||
Ref(ty::Region<'tcx>),
|
Ref(ty::Region<'tcx>),
|
||||||
Regular { ty: DefId, args: 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> {
|
impl<'tcx> ContainerTy<'tcx> {
|
||||||
fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
|
fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
|
||||||
match self {
|
match self {
|
||||||
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
|
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
|
||||||
Self::Regular { ty: container, args, arg: index } => {
|
Self::Regular { ty: container, args, has_self, arg: index } => {
|
||||||
let (DefKind::Struct
|
let (DefKind::Struct
|
||||||
| DefKind::Union
|
| DefKind::Union
|
||||||
| DefKind::Enum
|
| DefKind::Enum
|
||||||
| DefKind::TyAlias { .. }
|
| DefKind::TyAlias { .. }
|
||||||
| DefKind::Trait
|
| DefKind::Trait) = tcx.def_kind(container)
|
||||||
| DefKind::AssocTy
|
|
||||||
| DefKind::Variant) = tcx.def_kind(container)
|
|
||||||
else {
|
else {
|
||||||
return ObjectLifetimeDefault::Empty;
|
return ObjectLifetimeDefault::Empty;
|
||||||
};
|
};
|
||||||
|
|
||||||
let generics = tcx.generics_of(container);
|
let generics = tcx.generics_of(container);
|
||||||
let param = generics.params[index].def_id;
|
debug_assert_eq!(generics.parent_count, 0);
|
||||||
let default = tcx.object_lifetime_default(param);
|
|
||||||
|
|
||||||
|
// 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 {
|
match default {
|
||||||
rbv::ObjectLifetimeDefault::Param(lifetime) => {
|
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 index = generics.param_def_id_to_index[&lifetime];
|
||||||
let arg = args.skip_binder()[index as usize].expect_region();
|
let arg = args.skip_binder()[index as usize].expect_region();
|
||||||
ObjectLifetimeDefault::Arg(arg)
|
ObjectLifetimeDefault::Arg(arg)
|
||||||
|
@ -77,9 +77,10 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
|
|||||||
pub(crate) fn ty_args_to_args<'tcx>(
|
pub(crate) fn ty_args_to_args<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
|
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
|
||||||
mut skip_first: bool,
|
has_self: bool,
|
||||||
container: Option<DefId>,
|
container: Option<DefId>,
|
||||||
) -> Vec<GenericArg> {
|
) -> Vec<GenericArg> {
|
||||||
|
let mut skip_first = has_self;
|
||||||
let mut ret_val =
|
let mut ret_val =
|
||||||
Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));
|
Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));
|
||||||
|
|
||||||
@ -99,6 +100,7 @@ pub(crate) fn ty_args_to_args<'tcx>(
|
|||||||
container.map(|container| crate::clean::ContainerTy::Regular {
|
container.map(|container| crate::clean::ContainerTy::Regular {
|
||||||
ty: container,
|
ty: container,
|
||||||
args,
|
args,
|
||||||
|
has_self,
|
||||||
arg: index,
|
arg: index,
|
||||||
}),
|
}),
|
||||||
))),
|
))),
|
||||||
|
@ -65,3 +65,22 @@ pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
|
|||||||
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
|
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}
|
||||||
|
|
||||||
pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
|
pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);
|
||||||
|
|
||||||
|
// Trait objects inside of another trait object, a trait bound or an associated type.
|
||||||
|
|
||||||
|
pub trait Inner {}
|
||||||
|
pub trait Outer<T: ?Sized> {}
|
||||||
|
pub trait Base {
|
||||||
|
type Type<T: ?Sized>;
|
||||||
|
}
|
||||||
|
impl Base for () {
|
||||||
|
type Type<T: ?Sized> = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type NestedTraitObjects = dyn Outer<dyn Inner>;
|
||||||
|
|
||||||
|
pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> {
|
||||||
|
o
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type AssocTy = <() as Base>::Type<dyn Inner>;
|
||||||
|
@ -128,3 +128,18 @@
|
|||||||
// @has user/type.BareAmbiguousBoundStatic.html
|
// @has user/type.BareAmbiguousBoundStatic.html
|
||||||
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
|
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
|
||||||
pub use dyn_trait::BareAmbiguousBoundStatic;
|
pub use dyn_trait::BareAmbiguousBoundStatic;
|
||||||
|
|
||||||
|
// Regression test for issue #115179:
|
||||||
|
|
||||||
|
// @has user/type.NestedTraitObjects.html
|
||||||
|
// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;"
|
||||||
|
pub use dyn_trait::NestedTraitObjects;
|
||||||
|
|
||||||
|
// @has user/fn.apit_rpit.html
|
||||||
|
// @has - '//pre[@class="rust item-decl"]' \
|
||||||
|
// "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>"
|
||||||
|
pub use dyn_trait::apit_rpit;
|
||||||
|
|
||||||
|
// @has user/type.AssocTy.html
|
||||||
|
// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>"
|
||||||
|
pub use dyn_trait::AssocTy;
|
||||||
|
Loading…
Reference in New Issue
Block a user