diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 8ad09a9edc01c..58f7f34c7d4cf 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -331,9 +331,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { match br { // We only care about named late bound regions, as we need to add them // to the 'for<>' section - ty::BrNamed(_, name) => { - Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) - } + ty::BrNamed(_, name) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }), _ => None, } }) @@ -659,7 +660,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { bounds.insert(0, GenericBound::maybe_sized(self.cx)); } } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime { .. } => {} GenericParamDefKind::Const { ref mut default, .. } => { // We never want something like `impl` default.take(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b566239423e04..bb22da00576a6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -199,9 +199,10 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) { .collect_referenced_late_bound_regions(&poly_trait_ref) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) => { - Some(GenericParamDef { name, kind: GenericParamDefKind::Lifetime }) - } + ty::BrNamed(_, name) => Some(GenericParamDef { + name, + kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + }), _ => None, }) .collect(); @@ -412,7 +413,9 @@ impl<'tcx> Clean for ty::ProjectionTy<'tcx> { impl Clean for ty::GenericParamDef { fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { - ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime), + ty::GenericParamDefKind::Lifetime => { + (self.name, GenericParamDefKind::Lifetime { outlives: vec![] }) + } ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { let mut default = cx.tcx.type_of(self.def_id).clean(cx); @@ -462,21 +465,15 @@ impl Clean for hir::GenericParam<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { let (name, kind) = match self.kind { hir::GenericParamKind::Lifetime { .. } => { - let name = if !self.bounds.is_empty() { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, + let outlives = self + .bounds + .iter() + .map(|bound| match bound { + hir::GenericBound::Outlives(lt) => lt.clean(cx), _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - Symbol::intern(&s) - } else { - self.name.ident().name - }; - (name, GenericParamDefKind::Lifetime) + }) + .collect(); + (self.name.ident().name, GenericParamDefKind::Lifetime { outlives }) } hir::GenericParamKind::Type { ref default, synthetic } => ( self.name.ident().name, @@ -536,7 +533,7 @@ impl Clean for hir::Generics<'_> { .map(|param| { let param: GenericParamDef = param.clean(cx); match param.kind { - GenericParamDefKind::Lifetime => unreachable!(), + GenericParamDefKind::Lifetime { .. } => unreachable!(), GenericParamDefKind::Type { did, ref bounds, .. } => { cx.impl_trait_bounds.insert(did.into(), bounds.clone()); } @@ -569,7 +566,7 @@ impl Clean for hir::Generics<'_> { { for param in &mut generics.params { match param.kind { - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Lifetime { .. } => {} GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { if ¶m.name == name { mem::swap(bounds, ty_bounds); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4194c99c0ba70..d1820793d5882 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1231,7 +1231,9 @@ impl WherePredicate { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate enum GenericParamDefKind { - Lifetime, + Lifetime { + outlives: Vec, + }, Type { did: DefId, bounds: Vec, @@ -1257,7 +1259,7 @@ impl GenericParamDefKind { match self { GenericParamDefKind::Type { default, .. } => default.clone(), GenericParamDefKind::Const { ty, .. } => Some(ty.clone()), - GenericParamDefKind::Lifetime => None, + GenericParamDefKind::Lifetime { .. } => None, } } } @@ -1271,7 +1273,7 @@ crate struct GenericParamDef { impl GenericParamDef { crate fn is_synthetic_type_param(&self) -> bool { match self.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => false, + GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(), } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 54be830bf42e7..ea0458034899c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -155,9 +155,23 @@ impl clean::GenericParamDef { &'a self, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { - display_fn(move |f| match self.kind { - clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name), - clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => { + display_fn(move |f| match &self.kind { + clean::GenericParamDefKind::Lifetime { outlives } => { + write!(f, "{}", self.name)?; + + if !outlives.is_empty() { + f.write_str(": ")?; + for (i, lt) in outlives.iter().enumerate() { + if i != 0 { + f.write_str(" + ")?; + } + write!(f, "{}", lt.print())?; + } + } + + Ok(()) + } + clean::GenericParamDefKind::Type { bounds, default, .. } => { f.write_str(&*self.name.as_str())?; if !bounds.is_empty() { @@ -178,7 +192,7 @@ impl clean::GenericParamDef { Ok(()) } - clean::GenericParamDefKind::Const { ref ty, ref default, .. } => { + clean::GenericParamDefKind::Const { ty, default, .. } => { if f.alternate() { write!(f, "const {}: {:#}", self.name, ty.print(cx))?; } else { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 9453e6d35ee67..6f35e2e310641 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -326,7 +326,9 @@ impl FromWithTcx for GenericParamDefKind { fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self { use clean::GenericParamDefKind::*; match kind { - Lifetime => GenericParamDefKind::Lifetime, + Lifetime { outlives } => GenericParamDefKind::Lifetime { + outlives: outlives.into_iter().map(|lt| lt.0.to_string()).collect(), + }, Type { did: _, bounds, default, synthetic: _ } => GenericParamDefKind::Type { bounds: bounds.into_iter().map(|x| x.into_tcx(tcx)).collect(), default: default.map(|x| x.into_tcx(tcx)), diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 8bdf1a5981230..5089cc30a1e39 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -234,7 +234,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { ) }) .collect(), - format_version: 6, + format_version: 7, }; let mut p = self.out_path.clone(); p.push(output.index.get(&output.root).unwrap().name.clone().unwrap()); diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 38ba87322c238..37cdc94441df7 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -323,7 +323,7 @@ pub struct GenericParamDef { #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "snake_case")] pub enum GenericParamDefKind { - Lifetime, + Lifetime { outlives: Vec }, Type { bounds: Vec, default: Option }, Const { ty: Type, default: Option }, } diff --git a/src/test/rustdoc-json/structs/with_primitives.rs b/src/test/rustdoc-json/structs/with_primitives.rs index ea98676863b5e..9e64317ec203f 100644 --- a/src/test/rustdoc-json/structs/with_primitives.rs +++ b/src/test/rustdoc-json/structs/with_primitives.rs @@ -1,7 +1,7 @@ // @has with_primitives.json "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\" // @has - "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\" // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\" -// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind" \"lifetime\" +// @has - "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" [] // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.struct_type" \"plain\" // @has - "$.index[*][?(@.name=='WithPrimitives')].inner.fields_stripped" true pub struct WithPrimitives<'a> {