From d2eccb028f103fce73fac7951895d4c1eeae89f2 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 16 Jan 2022 13:05:29 +0800 Subject: [PATCH 1/5] Do not display ~const in rustdoc --- src/librustdoc/html/format.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index c0115bfc6d4fa..3aa8421456b8d 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -424,7 +424,8 @@ impl clean::GenericBound { let modifier_str = match modifier { hir::TraitBoundModifier::None => "", hir::TraitBoundModifier::Maybe => "?", - hir::TraitBoundModifier::MaybeConst => "~const", + // ~const is experimental; do not display those bounds in rustdoc + hir::TraitBoundModifier::MaybeConst => "", }; if f.alternate() { write!(f, "{}{:#}", modifier_str, ty.print(cx)) From 5406cbfb1c498812de69200c9ad8db2b5b25eff7 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 22 Jan 2022 14:46:19 +0800 Subject: [PATCH 2/5] Do not display hidden `~const Drop` bounds --- src/librustdoc/html/format.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 3aa8421456b8d..f703a67894939 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -279,7 +279,24 @@ crate fn print_where_clause<'a, 'tcx: 'a>( clause.push_str(" where"); } } - for (i, pred) in gens.where_predicates.iter().enumerate() { + + #[derive(Clone, Copy)] + enum Print<'a> { + Predicate(&'a clean::WherePredicate), + Comma, + } + + for pred in gens.where_predicates.iter().filter(|pred| { + !matches!(pred, clean::WherePredicate::BoundPredicate { bounds, .. } if bounds.is_empty()) + }).map(Print::Predicate).intersperse(Print::Comma) { + let pred = match pred { + Print::Predicate(pred) => pred, + Print::Comma => { + clause.push(','); + continue; + } + }; + if f.alternate() { clause.push(' '); } else { @@ -338,13 +355,10 @@ crate fn print_where_clause<'a, 'tcx: 'a>( } } } - - if i < gens.where_predicates.len() - 1 || end_newline { - clause.push(','); - } } if end_newline { + clause.push(','); // add a space so stripping
tags and breaking spaces still renders properly if f.alternate() { clause.push(' '); From 9c0141a4907e9255c5583304def3c16d357a5a14 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 23 Jan 2022 00:13:42 +0800 Subject: [PATCH 3/5] Bless rustdoc test --- src/librustdoc/html/format.rs | 166 +++++++++--------- .../const-generics/generic_const_exprs.rs | 2 +- 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f703a67894939..699be93b1230f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -143,11 +143,14 @@ impl Buffer { } } -fn comma_sep(items: impl Iterator) -> impl fmt::Display { +fn comma_sep( + items: impl Iterator, + space_after_comma: bool, +) -> impl fmt::Display { display_fn(move |f| { for (i, item) in items.enumerate() { if i != 0 { - write!(f, ", ")?; + write!(f, ",{}", if space_after_comma { " " } else { "" })?; } fmt::Display::fmt(&item, f)?; } @@ -248,9 +251,9 @@ impl clean::Generics { } if f.alternate() { - write!(f, "<{:#}>", comma_sep(real_params.map(|g| g.print(cx)))) + write!(f, "<{:#}>", comma_sep(real_params.map(|g| g.print(cx)), true)) } else { - write!(f, "<{}>", comma_sep(real_params.map(|g| g.print(cx)))) + write!(f, "<{}>", comma_sep(real_params.map(|g| g.print(cx)), true)) } }) } @@ -266,10 +269,80 @@ crate fn print_where_clause<'a, 'tcx: 'a>( end_newline: bool, ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { - if gens.where_predicates.is_empty() { + let mut where_predicates = gens.where_predicates.iter().filter(|pred| { + !matches!(pred, clean::WherePredicate::BoundPredicate { bounds, .. } if bounds.is_empty()) + }).map(|pred| { + display_fn(move |f| { + if f.alternate() { + f.write_str(" ")?; + } else { + f.write_str("
")?; + } + + match pred { + clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { + let bounds = bounds; + let for_prefix = match bound_params.len() { + 0 => String::new(), + _ if f.alternate() => { + format!( + "for<{:#}> ", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ) + } + _ => format!( + "for<{}> ", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ), + }; + + if f.alternate() { + write!( + f, + "{}{:#}: {:#}", + for_prefix, + ty.print(cx), + print_generic_bounds(bounds, cx) + ) + } else { + write!( + f, + "{}{}: {}", + for_prefix, + ty.print(cx), + print_generic_bounds(bounds, cx) + ) + } + } + clean::WherePredicate::RegionPredicate { lifetime, bounds } => { + write!( + f, + "{}: {}", + lifetime.print(), + bounds + .iter() + .map(|b| b.print(cx).to_string()) + .collect::>() + .join(" + ") + ) + } + clean::WherePredicate::EqPredicate { lhs, rhs } => { + if f.alternate() { + write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx),) + } else { + write!(f, "{} == {}", lhs.print(cx), rhs.print(cx),) + } + } + } + }) + }).peekable(); + + if where_predicates.peek().is_none() { return Ok(()); } + let mut clause = String::new(); + if f.alternate() { clause.push_str(" where"); } else { @@ -280,82 +353,7 @@ crate fn print_where_clause<'a, 'tcx: 'a>( } } - #[derive(Clone, Copy)] - enum Print<'a> { - Predicate(&'a clean::WherePredicate), - Comma, - } - - for pred in gens.where_predicates.iter().filter(|pred| { - !matches!(pred, clean::WherePredicate::BoundPredicate { bounds, .. } if bounds.is_empty()) - }).map(Print::Predicate).intersperse(Print::Comma) { - let pred = match pred { - Print::Predicate(pred) => pred, - Print::Comma => { - clause.push(','); - continue; - } - }; - - if f.alternate() { - clause.push(' '); - } else { - clause.push_str("
"); - } - - match pred { - clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { - let bounds = bounds; - let for_prefix = match bound_params.len() { - 0 => String::new(), - _ if f.alternate() => { - format!( - "for<{:#}> ", - comma_sep(bound_params.iter().map(|lt| lt.print())) - ) - } - _ => format!( - "for<{}> ", - comma_sep(bound_params.iter().map(|lt| lt.print())) - ), - }; - - if f.alternate() { - clause.push_str(&format!( - "{}{:#}: {:#}", - for_prefix, - ty.print(cx), - print_generic_bounds(bounds, cx) - )); - } else { - clause.push_str(&format!( - "{}{}: {}", - for_prefix, - ty.print(cx), - print_generic_bounds(bounds, cx) - )); - } - } - clean::WherePredicate::RegionPredicate { lifetime, bounds } => { - clause.push_str(&format!( - "{}: {}", - lifetime.print(), - bounds - .iter() - .map(|b| b.print(cx).to_string()) - .collect::>() - .join(" + ") - )); - } - clean::WherePredicate::EqPredicate { lhs, rhs } => { - if f.alternate() { - clause.push_str(&format!("{:#} == {:#}", lhs.print(cx), rhs.print(cx),)); - } else { - clause.push_str(&format!("{} == {}", lhs.print(cx), rhs.print(cx),)); - } - } - } - } + clause.push_str(&comma_sep(where_predicates, false).to_string()); if end_newline { clause.push(','); @@ -408,13 +406,13 @@ impl clean::PolyTrait { write!( f, "for<{:#}> ", - comma_sep(self.generic_params.iter().map(|g| g.print(cx))) + comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) )?; } else { write!( f, "for<{}> ", - comma_sep(self.generic_params.iter().map(|g| g.print(cx))) + comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) )?; } } @@ -1125,7 +1123,7 @@ impl clean::BareFunctionDecl { write!( f, "for<{}> ", - comma_sep(self.generic_params.iter().map(|g| g.print(cx))) + comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) ) } else { Ok(()) diff --git a/src/test/rustdoc/const-generics/generic_const_exprs.rs b/src/test/rustdoc/const-generics/generic_const_exprs.rs index 35036a89360e2..215ee228eb857 100644 --- a/src/test/rustdoc/const-generics/generic_const_exprs.rs +++ b/src/test/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 struct"]' \ -// 'pub struct Ice where [(); N + 1]: ;' +// 'pub struct Ice;' pub struct Ice where [(); N + 1]:; From 79f2180928982ebd8deb0b39bfa1c1c1dd7a0a59 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 22 Feb 2022 10:26:18 +1100 Subject: [PATCH 4/5] Add ui test --- src/test/rustdoc/rfc-2632-const-trait-impl.rs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/rustdoc/rfc-2632-const-trait-impl.rs diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs new file mode 100644 index 0000000000000..2adf69f6514cd --- /dev/null +++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs @@ -0,0 +1,60 @@ +// Test that we do not currently display `~const` in rustdoc +// as that syntax is currently provisional; `~const Drop` has +// no effect on stable code so it should be hidden as well. +// +// To future blessers: make sure that `const_trait_impl` is +// stabilized when changing `@!has` to `@has`, and please do +// not remove this test. +#![feature(const_trait_impl)] +#![crate_name = "foo"] + +pub struct S(T); + +// @!has foo/trait.Tr.html '//pre[@class="rust trait"]/code/a[@class="trait"]' '~const' +// @!has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Drop' +// @has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Clone' +// @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' '~const' +// @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' 'Drop' +// @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone' +pub trait Tr { + // @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const' + // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Drop' + // @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' + // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' 'Drop' + // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' + #[default_method_body_is_const] + fn a() where Option: ~const Drop + ~const Clone {} +} + +// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const' +// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Drop' +// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone' +// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const' +// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' 'Drop' +// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone' +impl const Tr for T where Option: ~const Drop + ~const Clone { + fn a() where Option: ~const Drop + ~const Clone {} +} + +// @!has foo/fn.foo.html '//pre[@class="rust fn"]/code/a[@class="trait"]' '~const' +// @!has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Drop' +// @has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Clone' +// @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' '~const' +// @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' 'Drop' +// @has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' ': Clone' +pub const fn foo() where Option: ~const Drop + ~const Clone { + F::a() +} + +impl S { + // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const' + // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Drop' + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' + // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' 'Drop' + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' + pub const fn foo() where B: ~const Drop + ~const Clone { + B::a() + } +} From 484936bbfcb09c357569198f9a5a21deed8dd041 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 22 Feb 2022 10:30:59 +1100 Subject: [PATCH 5/5] Address review comments --- src/librustdoc/html/format.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 699be93b1230f..9faf5431a6eba 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -282,18 +282,18 @@ crate fn print_where_clause<'a, 'tcx: 'a>( match pred { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { let bounds = bounds; - let for_prefix = match bound_params.len() { - 0 => String::new(), - _ if f.alternate() => { - format!( - "for<{:#}> ", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ) - } - _ => format!( + let for_prefix = if bound_params.is_empty() { + String::new() + } else if f.alternate() { + format!( + "for<{:#}> ", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ) + } else { + format!( "for<{}> ", comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ), + ) }; if f.alternate() {