Rollup merge of #94684 - compiler-errors:gat-anon-late-bound, r=notriddle

Fix rustdoc for GATs with with anonymous bound regions

Just use the logic that already worked for cleaning trait refs.

Fixes #94683
This commit is contained in:
Matthias Krüger 2022-03-07 06:44:05 +01:00 committed by GitHub
commit a1119fd699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 35 deletions

View File

@ -402,16 +402,7 @@ fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>)
PathSegment {
name: item.name,
args: GenericArgs::AngleBracketed {
args: ty.substs[generics.parent_count..]
.iter()
.map(|ty| match ty.unpack() {
ty::subst::GenericArgKind::Lifetime(lt) => {
GenericArg::Lifetime(lt.clean(cx).unwrap())
}
ty::subst::GenericArgKind::Type(ty) => GenericArg::Type(ty.clean(cx)),
ty::subst::GenericArgKind::Const(c) => GenericArg::Const(Box::new(c.clean(cx))),
})
.collect(),
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false),
bindings: Default::default(),
},
}
@ -1379,11 +1370,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>
});
if let Some(lt) = lifetime.cloned() {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned = if !lt.is_elided() {
lt.clean(cx)
} else {
self::types::Lifetime::elided()
};
let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
}
indices.lifetimes += 1;

View File

@ -77,16 +77,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
Crate { module, primitives, external_traits: cx.external_traits.clone() }
}
fn external_generic_args(
crate fn substs_to_args(
cx: &mut DocContext<'_>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
) -> GenericArgs {
let mut skip_self = has_self;
let mut ty_kind = None;
let args: Vec<_> = substs
substs: &[ty::subst::GenericArg<'_>],
mut skip_first: bool,
) -> Vec<GenericArg> {
substs
.iter()
.filter_map(|kind| match kind.unpack() {
GenericArgKind::Lifetime(lt) => match *lt {
@ -95,23 +91,32 @@ fn external_generic_args(
}
_ => lt.clean(cx).map(GenericArg::Lifetime),
},
GenericArgKind::Type(_) if skip_self => {
skip_self = false;
GenericArgKind::Type(_) if skip_first => {
skip_first = false;
None
}
GenericArgKind::Type(ty) => {
ty_kind = Some(ty.kind());
Some(GenericArg::Type(ty.clean(cx)))
}
GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))),
})
.collect();
.collect()
}
fn external_generic_args(
cx: &mut DocContext<'_>,
did: DefId,
has_self: bool,
bindings: Vec<TypeBinding>,
substs: SubstsRef<'_>,
) -> GenericArgs {
let args = substs_to_args(cx, &substs, has_self);
if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
let inputs = match ty_kind.unwrap() {
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
};
let inputs =
// The trait's first substitution is the one after self, if there is one.
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].kind {

View File

@ -0,0 +1,13 @@
#![crate_name = "foo"]
#![feature(generic_associated_types)]
pub trait Trait {
type Gat<'a>;
}
// Make sure that the elided lifetime shows up
// @has foo/type.T.html
// @has - "pub type T = "
// @has - "&lt;'_&gt;"
pub type T = fn(&<() as Trait>::Gat<'_>);