From 1d077d324c9a79709f646d8ef113deda37b2ff23 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 9 Jun 2025 21:04:09 +0000 Subject: [PATCH] WIP: Add implied bounds to rustdoc --- src/librustdoc/clean/mod.rs | 8 ++++++-- tests/rustdoc-json/implied-bounds.rs | 19 +++++++++++++++++++ tests/rustdoc/assoc/normalize-assoc-item.rs | 4 ++-- .../const-generics/generic_const_exprs.rs | 2 +- .../whitespace-after-where-clause.struct.html | 2 +- ...whitespace-after-where-clause.struct2.html | 3 ++- 6 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 tests/rustdoc-json/implied-bounds.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7658e7ad35f3a..afff700dc8737 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2830,9 +2830,13 @@ fn clean_maybe_renamed_item<'tcx>( generics: clean_generics(generics, cx), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), - ItemKind::Struct(_, generics, variant_data) => StructItem(Struct { + ItemKind::Struct(_, _, variant_data) => StructItem(Struct { ctor_kind: variant_data.ctor_kind(), - generics: clean_generics(generics, cx), + generics: clean_ty_generics( + cx, + cx.tcx.generics_of(def_id), + cx.tcx.predicates_of(def_id), + ), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro { diff --git a/tests/rustdoc-json/implied-bounds.rs b/tests/rustdoc-json/implied-bounds.rs new file mode 100644 index 0000000000000..01876c858158e --- /dev/null +++ b/tests/rustdoc-json/implied-bounds.rs @@ -0,0 +1,19 @@ +//@ count '$.index[?(@.name=="Foo")].inner.struct.generics.params[*]' 2 +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.params[0].name' \"\'a\" +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.params[0].kind.lifetime.outlives' [] +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.params[1].name' '"T"' +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.params[1].kind.type.bounds' '[]' +//@ count '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[*]' 1 +//@ count '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[*]' 1 +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[0].bound_predicate.type.generic' '"T"' +//@ count '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[0].bound_predicate.bounds[*]' 2 +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.path' '"Copy"' +//@ is '$.index[?(@.name=="Foo")].inner.struct.generics.where_predicates[0].bound_predicate.bounds[1].outlives' \"\'a\" +// ^^^^ The last bound donesn't exist anywhere in the source code ^^^^ + +pub struct Foo<'a, T: Copy>(&'a T); +// Desguars to: +// pub struct Foo<'a, T>(&'a T) where T: Copy + 'a; + +// FIXME: Needs more tests, at least +// - Implied 'a: 'b diff --git a/tests/rustdoc/assoc/normalize-assoc-item.rs b/tests/rustdoc/assoc/normalize-assoc-item.rs index 7ef9d3067e145..e7a0372488503 100644 --- a/tests/rustdoc/assoc/normalize-assoc-item.rs +++ b/tests/rustdoc/assoc/normalize-assoc-item.rs @@ -49,10 +49,10 @@ impl Trait for Generic { // These can't be normalized because they depend on a generic parameter. // However the user can choose whether the text should be displayed as `Inner::X` or `::X`. -//@ has 'normalize_assoc_item/struct.Unknown.html' '//pre[@class="rust item-decl"]' 'pub struct Unknown(pub ::X);' +//@ has 'normalize_assoc_item/struct.Unknown.html' '//pre[@class="rust item-decl"]' 'pub struct Unknown(pub ::X) where Inner: Trait;' pub struct Unknown(pub ::X); -//@ has 'normalize_assoc_item/struct.Unknown2.html' '//pre[@class="rust item-decl"]' 'pub struct Unknown2(pub Inner::X);' +//@ has 'normalize_assoc_item/struct.Unknown2.html' '//pre[@class="rust item-decl"]' 'pub struct Unknown2(pub Inner::X) where Inner: Trait;' pub struct Unknown2(pub Inner::X); trait Lifetimes<'a> { diff --git a/tests/rustdoc/const-generics/generic_const_exprs.rs b/tests/rustdoc/const-generics/generic_const_exprs.rs index c406fa5d03417..1fa7044b2e141 100644 --- a/tests/rustdoc/const-generics/generic_const_exprs.rs +++ b/tests/rustdoc/const-generics/generic_const_exprs.rs @@ -3,5 +3,5 @@ #![allow(incomplete_features)] // make sure that `ConstEvaluatable` predicates dont cause rustdoc to ICE #77647 //@ has foo/struct.Ice.html '//pre[@class="rust item-decl"]' \ -// 'pub struct Ice where [(); { _ }]:;' +// 'pub struct Ice;' pub struct Ice where [(); N + 1]:; diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc/whitespace-after-where-clause.struct.html index bc62a3a0015e3..f12ea12e6564e 100644 --- a/tests/rustdoc/whitespace-after-where-clause.struct.html +++ b/tests/rustdoc/whitespace-after-where-clause.struct.html @@ -1,5 +1,5 @@
pub struct Struct<'a, B>
where - B: ToOwned<()> + ?Sized + 'a,
{ + B: 'a + ToOwned<()> + ?Sized,{ pub a: &'a B, pub b: u32, }
\ No newline at end of file diff --git a/tests/rustdoc/whitespace-after-where-clause.struct2.html b/tests/rustdoc/whitespace-after-where-clause.struct2.html index 5aa8110c18f71..ee98613b4e8ab 100644 --- a/tests/rustdoc/whitespace-after-where-clause.struct2.html +++ b/tests/rustdoc/whitespace-after-where-clause.struct2.html @@ -1,4 +1,5 @@ -
pub struct Struct2<'a, B: ?Sized + ToOwned<()> + 'a> {
+
pub struct Struct2<'a, B>
where + B: ToOwned<()> + 'a + ?Sized,
{ pub a: &'a B, pub b: u32, }
\ No newline at end of file