Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Minimized example: Command: <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --Platform: See backtrace <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
I'll look into it! claim
Minimized this to a local-crate-only test, and working on a solution currently:

Discussion:
PathSegment { name: item.name, args: GenericArgs::AngleBracketed { <del> 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(), </del> <ins> args: substs_to_args(cx, &ty.substs[generics.parent_count..], false), </ins> bindings: Default::default(), }, }

}); if let Some(lt) = lifetime.cloned() { let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id); <del> let cleaned = if !lt.is_elided() { lt.clean(cx) } else { self::types::Lifetime::elided() }; </del> <ins> let cleaned = if !lt.is_elided() { lt.clean(cx) } else { Lifetime::elided() }; </ins> substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned)); } indices.lifetimes += 1;

Crate { module, primitives, external_traits: cx.external_traits.clone() } } <del> fn external_generic_args( </del> <ins> crate fn substs_to_args( </ins> cx: &mut DocContext<'_>, <del> 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 </del> <ins> substs: &[ty::subst::GenericArg<'_>], mut skip_first: bool, ) -> Vec<GenericArg> { substs </ins> .iter() .filter_map(|kind| match kind.unpack() { GenericArgKind::Lifetime(lt) => match *lt {

} _ => lt.clean(cx).map(GenericArg::Lifetime), }, <del> GenericArgKind::Type(_) if skip_self => { skip_self = false; </del> <ins> GenericArgKind::Type(_) if skip_first => { skip_first = false; </ins> None } <del> GenericArgKind::Type(ty) => { ty_kind = Some(ty.kind()); Some(GenericArg::Type(ty.clean(cx))) } </del> <ins> GenericArgKind::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), </ins> GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(ct.clean(cx)))), }) <del> .collect(); </del> <ins> .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); </ins> if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() { <del> let inputs = match ty_kind.unwrap() { ty::Tuple(tys) => tys.iter().map(|t| t.clean(cx)).collect(), _ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() }, }; </del> <ins> 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() }, }; </ins> let output = None; // FIXME(#20299) return type comes from a projection now // match types[1].kind {

<ins> #![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<'_>); </ins>