diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 63de870f07f45..e6fca29e23e5f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1050,14 +1050,11 @@ fn assoc_const( ty = print_type(ty, cx), )?; if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value { - // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the - // hood which adds noisy underscores and a type suffix to number literals. - // This hurts readability in this context especially when more complex expressions - // are involved and it doesn't add much of value. - // Find a way to print constants here without all that jazz. - let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); + let repr = konst.expr(tcx); if match value { AssocConstValue::TraitDefault(_) => true, // always show + // FIXME: Comparing against the special string "_" denoting overly complex const exprs + // is rather hacky; `ConstKind::expr` should have a richer return type. AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show AssocConstValue::None => unreachable!(), } { diff --git a/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html index 091dac3e4b261..310957ac1ae05 100644 --- a/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html +++ b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html @@ -1 +1 @@ -
Source

pub const X: i32 = 0i32

\ No newline at end of file +
Source

pub const X: i32 = 0

\ No newline at end of file diff --git a/tests/rustdoc-html/attributes.rs b/tests/rustdoc-html/attributes.rs index 429a42a7252cd..6032c3d388011 100644 --- a/tests/rustdoc-html/attributes.rs +++ b/tests/rustdoc-html/attributes.rs @@ -59,7 +59,7 @@ pub enum Enum { pub trait Trait { //@ has 'foo/trait.Trait.html' //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[unsafe(link_section = "bar")]' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0' #[unsafe(link_section = "bar")] const BAR: u32 = 0; diff --git a/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs b/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs new file mode 100644 index 0000000000000..ed0789dade574 --- /dev/null +++ b/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs @@ -0,0 +1,31 @@ +// Ensure that we properly print the value `1` as `1` in the initializer of associated constants +// that have user type "projection". +// +// We once used to evaluate the initializer in rustdoc and use rustc's MIR pretty-printer to +// render the resulting MIR const value. This pretty printer matches on the type to interpret +// the data and falls back to a cryptic `"{transmute(0x$data): $ty}"` for types it can't handle. +// Crucially, when constructing the MIR const we passed the unnormalized type of the initializer, +// i.e., the projection `::Ty` instead of the normalized `u32` which the +// pretty printer obviously can't handle. +// +// Now we no longer evaluate it and use a custom printer for the const expr. +// +// issue: + +#![crate_name = "it"] + +pub trait Trait { + type Ty; + + const CT: Self::Ty; +} + +pub struct Struct; + +impl Trait for Struct { + type Ty = u32; + + //@ has it/struct.Struct.html + //@ has - '//*[@id="associatedconstant.CT"]' 'const CT: Self::Ty = 1' + const CT: Self::Ty = 1; +} diff --git a/tests/rustdoc-html/constant/assoc-consts.rs b/tests/rustdoc-html/constant/assoc-consts.rs index 247b5b180a869..0994ec7517e3e 100644 --- a/tests/rustdoc-html/constant/assoc-consts.rs +++ b/tests/rustdoc-html/constant/assoc-consts.rs @@ -1,6 +1,6 @@ pub trait Foo { //@ has assoc_consts/trait.Foo.html '//pre[@class="rust item-decl"]' \ - // 'const FOO: usize = 13usize;' + // 'const FOO: usize = _;' //@ has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize' const FOO: usize = 12 + 1; //@ has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool' diff --git a/tests/rustdoc-html/deref/deref-to-primitive.rs b/tests/rustdoc-html/deref/deref-to-primitive.rs index 7a5a3cd8fd655..6fdc382b2213b 100644 --- a/tests/rustdoc-html/deref/deref-to-primitive.rs +++ b/tests/rustdoc-html/deref/deref-to-primitive.rs @@ -3,7 +3,7 @@ //@ has 'foo/struct.Foo.html' //@ has - '//*[@id="deref-methods-i32"]' 'Methods from Deref' //@ has - '//*[@id="deref-methods-i32-1"]//*[@id="associatedconstant.BITS"]/h4' \ -// 'pub const BITS: u32 = 32u32' +// 'pub const BITS: u32 = u32::BITS' pub struct Foo(i32); impl std::ops::Deref for Foo { diff --git a/tests/rustdoc-html/display-hidden-items.rs b/tests/rustdoc-html/display-hidden-items.rs index 40cd636e2fe29..8b0854d1ade81 100644 --- a/tests/rustdoc-html/display-hidden-items.rs +++ b/tests/rustdoc-html/display-hidden-items.rs @@ -20,7 +20,7 @@ pub trait TraitHidden {} //@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' pub trait Trait { //@ has 'foo/trait.Trait.html' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' #[doc(hidden)] const BAR: u32 = 0; @@ -44,7 +44,7 @@ impl Struct { } impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' } //@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' diff --git a/tests/rustdoc-html/impl/impl-associated-items-order.rs b/tests/rustdoc-html/impl/impl-associated-items-order.rs index 759e0f0b40095..3f1d047201636 100644 --- a/tests/rustdoc-html/impl/impl-associated-items-order.rs +++ b/tests/rustdoc-html/impl/impl-associated-items-order.rs @@ -16,7 +16,7 @@ impl Bar { // 'pub fn foo()' pub fn foo() {} //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'pub const X: u8 = 12u8' + // 'pub const X: u8 = 12' pub const X: u8 = 12; //@ has - '//*[@id="implementations-list"]//*[@class="impl-items"]/section[2]/h4' \ // 'pub type Y = u8' @@ -34,7 +34,7 @@ impl Foo for Bar { // 'type Z = u8' type Z = u8; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[1]/h4' \ - // 'const W: u32 = 12u32' + // 'const W: u32 = 12' const W: u32 = 12; //@ has - '//*[@id="trait-implementations-list"]//*[@class="impl-items"]/section[3]/h4' \ // 'fn yeay()' diff --git a/tests/rustdoc-ui/diverging-assoc-consts.rs b/tests/rustdoc-ui/diverging-assoc-consts.rs new file mode 100644 index 0000000000000..fd0a177e7c4b8 --- /dev/null +++ b/tests/rustdoc-ui/diverging-assoc-consts.rs @@ -0,0 +1,33 @@ +// Ensure that we don't unconditionally evaluate the initializer of associated constants. +// +// We once used to evaluate them so we could display more kinds of expressions +// (like `1 + 1` as `2`) given the fact that we generally only want to render +// literals (otherwise we would risk dumping extremely large exprs or leaking +// private struct fields). +// +// However, that deviated from rustc's behavior, made rustdoc accept less code +// and was understandably surprising to users. So let's not. +// +// In the future we *might* provide users a mechanism to control this behavior. +// E.g., via a new `#[doc(...)]` attribute. +// +// See also: +// issue: +// issue: + +//@ check-pass + +pub struct Type; + +impl Type { + pub const K0: () = panic!(); + pub const K1: std::convert::Infallible = loop {}; +} + +pub trait Trait { + const K2: i32 = panic!(); +} + +impl Trait for Type { + const K2: i32 = loop {}; +}