Skip to content

Commit 890a44f

Browse files
Fix rustdoc for GATs with with anonymous bound regions
1 parent c38b8a8 commit 890a44f

File tree

3 files changed

+40
-35
lines changed

3 files changed

+40
-35
lines changed

src/librustdoc/clean/mod.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -402,16 +402,7 @@ fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>)
402402
PathSegment {
403403
name: item.name,
404404
args: GenericArgs::AngleBracketed {
405-
args: ty.substs[generics.parent_count..]
406-
.iter()
407-
.map(|ty| match ty.unpack() {
408-
ty::subst::GenericArgKind::Lifetime(lt) => {
409-
GenericArg::Lifetime(lt.clean(cx).unwrap())
410-
}
411-
ty::subst::GenericArgKind::Type(ty) => GenericArg::Type(ty.clean(cx)),
412-
ty::subst::GenericArgKind::Const(c) => GenericArg::Const(Box::new(c.clean(cx))),
413-
})
414-
.collect(),
405+
args: substs_to_args(cx, &ty.substs[generics.parent_count..], false),
415406
bindings: Default::default(),
416407
},
417408
}
@@ -1379,11 +1370,7 @@ fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>
13791370
});
13801371
if let Some(lt) = lifetime.cloned() {
13811372
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
1382-
let cleaned = if !lt.is_elided() {
1383-
lt.clean(cx)
1384-
} else {
1385-
self::types::Lifetime::elided()
1386-
};
1373+
let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() };
13871374
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
13881375
}
13891376
indices.lifetimes += 1;

src/librustdoc/clean/utils.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,12 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate {
7777
Crate { module, primitives, external_traits: cx.external_traits.clone() }
7878
}
7979

80-
fn external_generic_args(
80+
crate fn substs_to_args(
8181
cx: &mut DocContext<'_>,
82-
did: DefId,
83-
has_self: bool,
84-
bindings: Vec<TypeBinding>,
85-
substs: SubstsRef<'_>,
86-
) -> GenericArgs {
87-
let mut skip_self = has_self;
88-
let mut ty_kind = None;
89-
let args: Vec<_> = substs
82+
substs: &[ty::subst::GenericArg<'_>],
83+
mut skip_first: bool,
84+
) -> Vec<GenericArg> {
85+
substs
9086
.iter()
9187
.filter_map(|kind| match kind.unpack() {
9288
GenericArgKind::Lifetime(lt) => match *lt {
@@ -95,23 +91,32 @@ fn external_generic_args(
9591
}
9692
_ => lt.clean(cx).map(GenericArg::Lifetime),
9793
},
98-
GenericArgKind::Type(_) if skip_self => {
99-
skip_self = false;
94+
GenericArgKind::Type(_) if skip_first => {
95+
skip_first = false;
10096
None
10197
}
102-
GenericArgKind::Type(ty) => {
103-
ty_kind = Some(ty.kind());
104-
Some(GenericArg::Type(ty.clean(cx)))
105-
}
98+
GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
10699
GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))),
107100
})
108-
.collect();
101+
.collect()
102+
}
103+
104+
fn external_generic_args(
105+
cx: &mut DocContext<'_>,
106+
did: DefId,
107+
has_self: bool,
108+
bindings: Vec<TypeBinding>,
109+
substs: SubstsRef<'_>,
110+
) -> GenericArgs {
111+
let args = substs_to_args(cx, &substs, has_self);
109112

110113
if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
111-
let inputs = match ty_kind.unwrap() {
112-
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
113-
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
114-
};
114+
let inputs =
115+
// The trait's first substitution is the one after self, if there is one.
116+
match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
117+
ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(),
118+
_ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
119+
};
115120
let output = None;
116121
// FIXME(#20299) return type comes from a projection now
117122
// match types[1].kind {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![crate_name = "foo"]
2+
#![feature(generic_associated_types)]
3+
4+
pub trait Trait {
5+
type Gat<'a>;
6+
}
7+
8+
// Make sure that the elided lifetime shows up
9+
10+
// @has foo/type.T.html
11+
// @has - "pub type T = "
12+
// @has - "&lt;'_&gt;"
13+
pub type T = fn(&<() as Trait>::Gat<'_>);

0 commit comments

Comments
 (0)