summary refs log tree commit diff
path: root/tests/rustdoc/constant
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-05-05 17:01:08 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2025-05-05 17:47:18 +0200
commitb84f4cc39e99f801dcd37125dffa67eb796c85b8 (patch)
tree071def2349dabae166fd66b06ee9346aa825abb9 /tests/rustdoc/constant
parentbe71d8b24f1aebe9c45279d95a76db8fa6a62574 (diff)
downloadrust-b84f4cc39e99f801dcd37125dffa67eb796c85b8.tar.gz
rust-b84f4cc39e99f801dcd37125dffa67eb796c85b8.zip
Created `tests/rustdoc/impl` subfolder to limit number of files at the top level
Diffstat (limited to 'tests/rustdoc/constant')
-rw-r--r--tests/rustdoc/constant/assoc-consts-underscore.rs30
-rw-r--r--tests/rustdoc/constant/assoc-consts-version.rs15
-rw-r--r--tests/rustdoc/constant/assoc-consts.rs103
-rw-r--r--tests/rustdoc/constant/associated-consts.rs51
-rw-r--r--tests/rustdoc/constant/const-display.rs92
-rw-r--r--tests/rustdoc/constant/const-doc.rs19
-rw-r--r--tests/rustdoc/constant/const-effect-param.rs14
-rw-r--r--tests/rustdoc/constant/const-underscore.rs7
-rw-r--r--tests/rustdoc/constant/const-value-display.rs9
-rw-r--r--tests/rustdoc/constant/const.rs10
-rw-r--r--tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs17
-rw-r--r--tests/rustdoc/constant/generic-const-items.rs38
-rw-r--r--tests/rustdoc/constant/generic_const_exprs.rs24
-rw-r--r--tests/rustdoc/constant/glob-shadowing-const.rs20
-rw-r--r--tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs91
-rw-r--r--tests/rustdoc/constant/hide-complex-unevaluated-consts.rs71
-rw-r--r--tests/rustdoc/constant/ice-associated-const-equality-105952.rs15
-rw-r--r--tests/rustdoc/constant/legacy-const-generic.rs16
-rw-r--r--tests/rustdoc/constant/link-assoc-const.rs16
-rw-r--r--tests/rustdoc/constant/redirect-const.rs13
-rw-r--r--tests/rustdoc/constant/rfc-2632-const-trait-impl.rs73
-rw-r--r--tests/rustdoc/constant/show-const-contents.rs68
22 files changed, 812 insertions, 0 deletions
diff --git a/tests/rustdoc/constant/assoc-consts-underscore.rs b/tests/rustdoc/constant/assoc-consts-underscore.rs
new file mode 100644
index 00000000000..f48098094db
--- /dev/null
+++ b/tests/rustdoc/constant/assoc-consts-underscore.rs
@@ -0,0 +1,30 @@
+pub struct Struct {
+    _private: (),
+}
+
+pub trait Trait {
+    //@ has assoc_consts_underscore/trait.Trait.html '//pre[@class="rust item-decl"]' \
+    //      'const REQUIRED: Struct;'
+    //@ !has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct = _'
+    //@ has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct'
+    const REQUIRED: Struct;
+    //@ has - '//pre[@class="rust item-decl"]' 'const OPTIONAL: Struct = _;'
+    //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _'
+    const OPTIONAL: Struct = Struct { _private: () };
+}
+
+impl Trait for Struct {
+    //@ !has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \
+    //      'const REQUIRED: Struct = _'
+    //@ has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct'
+    const REQUIRED: Struct = Struct { _private: () };
+    //@ !has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _'
+    //@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct'
+    const OPTIONAL: Struct = Struct { _private: () };
+}
+
+impl Struct {
+    //@ !has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _'
+    //@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct'
+    pub const INHERENT: Struct = Struct { _private: () };
+}
diff --git a/tests/rustdoc/constant/assoc-consts-version.rs b/tests/rustdoc/constant/assoc-consts-version.rs
new file mode 100644
index 00000000000..db4d759acab
--- /dev/null
+++ b/tests/rustdoc/constant/assoc-consts-version.rs
@@ -0,0 +1,15 @@
+#![crate_name = "foo"]
+
+#![feature(staged_api)]
+
+#![stable(since="1.1.1", feature="rust1")]
+
+#[stable(since="1.1.1", feature="rust1")]
+pub struct SomeStruct;
+
+impl SomeStruct {
+    //@ has 'foo/struct.SomeStruct.html' \
+    //   '//*[@id="associatedconstant.SOME_CONST"]//span[@class="since"]' '1.1.2'
+    #[stable(since="1.1.2", feature="rust2")]
+    pub const SOME_CONST: usize = 0;
+}
diff --git a/tests/rustdoc/constant/assoc-consts.rs b/tests/rustdoc/constant/assoc-consts.rs
new file mode 100644
index 00000000000..247b5b180a8
--- /dev/null
+++ b/tests/rustdoc/constant/assoc-consts.rs
@@ -0,0 +1,103 @@
+pub trait Foo {
+    //@ has assoc_consts/trait.Foo.html '//pre[@class="rust item-decl"]' \
+    //      'const FOO: usize = 13usize;'
+    //@ has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize'
+    const FOO: usize = 12 + 1;
+    //@ has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
+    const FOO_NO_DEFAULT: bool;
+    //@ !hasraw - FOO_HIDDEN
+    #[doc(hidden)]
+    const FOO_HIDDEN: u8 = 0;
+}
+
+pub struct Bar;
+
+impl Foo for Bar {
+    //@ has assoc_consts/struct.Bar.html '//h3[@class="code-header"]' 'impl Foo for Bar'
+    //@ has - '//*[@id="associatedconstant.FOO"]' 'const FOO: usize'
+    const FOO: usize = 12;
+    //@ has - '//*[@id="associatedconstant.FOO_NO_DEFAULT"]' 'const FOO_NO_DEFAULT: bool'
+    const FOO_NO_DEFAULT: bool = false;
+    //@ !hasraw - FOO_HIDDEN
+    #[doc(hidden)]
+    const FOO_HIDDEN: u8 = 0;
+}
+
+impl Bar {
+    //@ has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.BAR"]' \
+    //      'const BAR: usize'
+    pub const BAR: usize = 3;
+
+    //@ has - '//*[@id="associatedconstant.BAR_ESCAPED"]' \
+    //      "const BAR_ESCAPED: &'static str = \"<em>markup</em>\""
+    pub const BAR_ESCAPED: &'static str = "<em>markup</em>";
+}
+
+pub struct Baz<'a, U: 'a, T>(T, &'a [U]);
+
+impl Bar {
+    //@ has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.BAZ"]' \
+    //      "const BAZ: Baz<'static, u8, u32>"
+    pub const BAZ: Baz<'static, u8, u32> = Baz(321, &[1, 2, 3]);
+}
+
+pub fn f(_: &(ToString + 'static)) {}
+
+impl Bar {
+    //@ has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
+    //      "const F: fn(&(dyn ToString + 'static))"
+    pub const F: fn(_: &(ToString + 'static)) = f;
+}
+
+impl Bar {
+    //@ !hasraw assoc_consts/struct.Bar.html 'BAR_PRIVATE'
+    const BAR_PRIVATE: char = 'a';
+    //@ !hasraw assoc_consts/struct.Bar.html 'BAR_HIDDEN'
+    #[doc(hidden)]
+    pub const BAR_HIDDEN: &'static str = "a";
+}
+
+//@ has assoc_consts/trait.Qux.html
+pub trait Qux {
+    //@ has - '//*[@id="associatedconstant.QUX0"]' 'const QUX0: u8'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX0 in trait."
+    /// Docs for QUX0 in trait.
+    const QUX0: u8;
+    //@ has - '//*[@id="associatedconstant.QUX1"]' 'const QUX1: i8'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX1 in trait."
+    /// Docs for QUX1 in trait.
+    const QUX1: i8;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT12 in trait."
+    /// Docs for QUX_DEFAULT12 in trait.
+    const QUX_DEFAULT0: u16 = 1;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in trait."
+    /// Docs for QUX_DEFAULT1 in trait.
+    const QUX_DEFAULT1: i16 = 2;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT2"]' 'const QUX_DEFAULT2: u32'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT2 in trait."
+    /// Docs for QUX_DEFAULT2 in trait.
+    const QUX_DEFAULT2: u32 = 3;
+}
+
+//@ has assoc_consts/struct.Bar.html '//h3[@class="code-header"]' 'impl Qux for Bar'
+impl Qux for Bar {
+    //@ has - '//*[@id="associatedconstant.QUX0"]' 'const QUX0: u8'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX0 in trait."
+    /// Docs for QUX0 in trait.
+    const QUX0: u8 = 4;
+    //@ has - '//*[@id="associatedconstant.QUX1"]' 'const QUX1: i8'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX1 in impl."
+    /// Docs for QUX1 in impl.
+    const QUX1: i8 = 5;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT0"]' 'const QUX_DEFAULT0: u16'
+    //@ has - '//div[@class="impl-items"]//*[@class="docblock"]' "Docs for QUX_DEFAULT12 in trait."
+    const QUX_DEFAULT0: u16 = 6;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT1"]' 'const QUX_DEFAULT1: i16'
+    //@ has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT1 in impl."
+    /// Docs for QUX_DEFAULT1 in impl.
+    const QUX_DEFAULT1: i16 = 7;
+    //@ has - '//*[@id="associatedconstant.QUX_DEFAULT2"]' 'const QUX_DEFAULT2: u32'
+    //@ has - '//div[@class="impl-items"]//*[@class="docblock"]' "Docs for QUX_DEFAULT2 in trait."
+}
diff --git a/tests/rustdoc/constant/associated-consts.rs b/tests/rustdoc/constant/associated-consts.rs
new file mode 100644
index 00000000000..2a7269a89be
--- /dev/null
+++ b/tests/rustdoc/constant/associated-consts.rs
@@ -0,0 +1,51 @@
+#![crate_name = "foo"]
+
+pub trait Trait {
+    const FOO: u32 = 12;
+
+    fn foo();
+}
+
+pub struct Bar;
+
+//@ has 'foo/struct.Bar.html'
+//@ !has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
+//@ !has - '//div[@class="sidebar-elems"]//a' 'FOO'
+impl Trait for Bar {
+    const FOO: u32 = 1;
+
+    fn foo() {}
+}
+
+pub enum Foo {
+    A,
+}
+
+//@ has 'foo/enum.Foo.html'
+//@ !has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
+//@ !has - '//div[@class="sidebar-elems"]//a' 'FOO'
+impl Trait for Foo {
+    const FOO: u32 = 1;
+
+    fn foo() {}
+}
+
+pub struct Baz;
+
+//@ has 'foo/struct.Baz.html'
+//@ has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
+//@ has - '//div[@class="sidebar-elems"]//a' 'FOO'
+impl Baz {
+    pub const FOO: u32 = 42;
+}
+
+pub enum Quux {
+    B,
+}
+
+//@ has 'foo/enum.Quux.html'
+//@ has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
+//@ has - '//div[@class="sidebar-elems"]//a' 'FOO'
+impl Quux {
+    pub const FOO: u32 = 42;
+}
diff --git a/tests/rustdoc/constant/const-display.rs b/tests/rustdoc/constant/const-display.rs
new file mode 100644
index 00000000000..bc4270c421d
--- /dev/null
+++ b/tests/rustdoc/constant/const-display.rs
@@ -0,0 +1,92 @@
+#![crate_name = "foo"]
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#![feature(foo, foo2)]
+#![feature(staged_api)]
+
+//@ has 'foo/fn.foo.html' '//pre' 'pub fn foo() -> u32'
+//@ has - '//span[@class="since"]' '1.0.0 (const: unstable)'
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo", issue = "none")]
+pub const fn foo() -> u32 { 42 }
+
+//@ has 'foo/fn.foo_unsafe.html' '//pre' 'pub unsafe fn foo_unsafe() -> u32'
+//@ has - '//span[@class="since"]' '1.0.0 (const: unstable)'
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo", issue = "none")]
+pub const unsafe fn foo_unsafe() -> u32 { 42 }
+
+//@ has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
+//@ !hasraw - '//span[@class="since"]'
+#[unstable(feature = "humans", issue = "none")]
+pub const fn foo2() -> u32 { 42 }
+
+//@ has 'foo/fn.foo3.html' '//pre' 'pub const fn foo3() -> u32'
+//@ !hasraw - '//span[@class="since"]'
+#[unstable(feature = "humans", issue = "none")]
+#[rustc_const_unstable(feature = "humans", issue = "none")]
+pub const fn foo3() -> u32 { 42 }
+
+//@ has 'foo/fn.bar2.html' '//pre' 'pub const fn bar2() -> u32'
+//@ has - //span '1.0.0 (const: 1.0.0)'
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+pub const fn bar2() -> u32 { 42 }
+
+
+//@ has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'
+//@ !hasraw - '//span[@class="since"]'
+#[unstable(feature = "foo2", issue = "none")]
+pub const unsafe fn foo2_gated() -> u32 { 42 }
+
+//@ has 'foo/fn.bar2_gated.html' '//pre' 'pub const unsafe fn bar2_gated() -> u32'
+//@ has - '//span[@class="since"]' '1.0.0 (const: 1.0.0)'
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+pub const unsafe fn bar2_gated() -> u32 { 42 }
+
+#[unstable(
+    feature = "humans",
+    reason = "who ever let humans program computers, we're apparently really bad at it",
+    issue = "none",
+)]
+pub mod unstable {
+    //@ has 'foo/unstable/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
+    //@ !hasraw - '//span[@class="since"]'
+    pub const unsafe fn bar_not_gated() -> u32 { 42 }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Foo;
+
+impl Foo {
+    //@ has 'foo/struct.Foo.html' '//*[@id="method.gated"]/h4[@class="code-header"]' 'pub fn gated() -> u32'
+    //@ has - '//span[@class="since"]' '1.0.0 (const: unstable)'
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature="foo", issue = "none")]
+    pub const fn gated() -> u32 { 42 }
+
+    //@ has 'foo/struct.Foo.html' '//*[@id="method.gated_unsafe"]/h4[@class="code-header"]' 'pub unsafe fn gated_unsafe() -> u32'
+    //@ has - '//span[@class="since"]' '1.0.0 (const: unstable)'
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature="foo", issue = "none")]
+    pub const unsafe fn gated_unsafe() -> u32 { 42 }
+
+    //@ has 'foo/struct.Foo.html' '//*[@id="method.stable_impl"]/h4[@class="code-header"]' 'pub const fn stable_impl() -> u32'
+    //@ has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)'
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const2", since = "1.2.0")]
+    pub const fn stable_impl() -> u32 { 42 }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Bar;
+
+impl Bar {
+    // Show non-const stabilities that are the same as the enclosing item.
+    //@ has 'foo/struct.Bar.html' '//span[@class="since"]' '1.0.0 (const: 1.2.0)'
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const2", since = "1.2.0")]
+    pub const fn stable_impl() -> u32 { 42 }
+}
diff --git a/tests/rustdoc/constant/const-doc.rs b/tests/rustdoc/constant/const-doc.rs
new file mode 100644
index 00000000000..f33083a267c
--- /dev/null
+++ b/tests/rustdoc/constant/const-doc.rs
@@ -0,0 +1,19 @@
+use std::marker::PhantomData;
+
+pub struct Foo<'a> {
+    f: PhantomData<&'a u32>,
+}
+
+pub struct ContentType {
+    pub ttype: Foo<'static>,
+    pub subtype: Foo<'static>,
+    pub params: Option<Foo<'static>>,
+}
+
+impl ContentType {
+    //@ has const_doc/struct.ContentType.html
+    //@ has  - '//*[@id="associatedconstant.Any"]' 'const Any: ContentType'
+    pub const Any: ContentType = ContentType { ttype: Foo { f: PhantomData, },
+                                               subtype: Foo { f: PhantomData, },
+                                               params: None, };
+}
diff --git a/tests/rustdoc/constant/const-effect-param.rs b/tests/rustdoc/constant/const-effect-param.rs
new file mode 100644
index 00000000000..cceb0adac30
--- /dev/null
+++ b/tests/rustdoc/constant/const-effect-param.rs
@@ -0,0 +1,14 @@
+// Check that we don't render host effect parameters & arguments.
+
+#![crate_name = "foo"]
+#![feature(const_trait_impl)]
+
+#[const_trait]
+pub trait Tr {
+    fn f();
+}
+
+//@ has foo/fn.g.html
+//@ has - '//pre[@class="rust item-decl"]' 'pub const fn g<T: Tr>()'
+/// foo
+pub const fn g<T: ~const Tr>() {}
diff --git a/tests/rustdoc/constant/const-underscore.rs b/tests/rustdoc/constant/const-underscore.rs
new file mode 100644
index 00000000000..fafc4b4e25c
--- /dev/null
+++ b/tests/rustdoc/constant/const-underscore.rs
@@ -0,0 +1,7 @@
+//@ compile-flags: --document-private-items
+
+//@ !has const_underscore/constant._.html
+const _: () = {
+    #[no_mangle]
+    extern "C" fn implementation_detail() {}
+};
diff --git a/tests/rustdoc/constant/const-value-display.rs b/tests/rustdoc/constant/const-value-display.rs
new file mode 100644
index 00000000000..658978a3490
--- /dev/null
+++ b/tests/rustdoc/constant/const-value-display.rs
@@ -0,0 +1,9 @@
+#![crate_name = "foo"]
+
+//@ has 'foo/constant.HOUR_IN_SECONDS.html'
+//@ has - '//*[@class="rust item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = _; // 3_600u64'
+pub const HOUR_IN_SECONDS: u64 = 60 * 60;
+
+//@ has 'foo/constant.NEGATIVE.html'
+//@ has - '//*[@class="rust item-decl"]//code' 'pub const NEGATIVE: i64 = _; // -3_600i64'
+pub const NEGATIVE: i64 = -60 * 60;
diff --git a/tests/rustdoc/constant/const.rs b/tests/rustdoc/constant/const.rs
new file mode 100644
index 00000000000..fe6a828505a
--- /dev/null
+++ b/tests/rustdoc/constant/const.rs
@@ -0,0 +1,10 @@
+#![crate_type="lib"]
+
+pub struct Foo;
+
+impl Foo {
+    //@ has const/struct.Foo.html '//*[@id="method.new"]//h4[@class="code-header"]' 'const unsafe fn new'
+    pub const unsafe fn new() -> Foo {
+        Foo
+    }
+}
diff --git a/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs b/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs
new file mode 100644
index 00000000000..c9408ef3360
--- /dev/null
+++ b/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs
@@ -0,0 +1,17 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait Enumerable {
+    const N: usize;
+}
+
+#[derive(Clone)]
+pub struct SymmetricGroup<S>
+where
+    S: Enumerable,
+    [(); S::N]: Sized,
+{
+    _phantom: std::marker::PhantomData<S>,
+}
+
+fn main() {}
diff --git a/tests/rustdoc/constant/generic-const-items.rs b/tests/rustdoc/constant/generic-const-items.rs
new file mode 100644
index 00000000000..31c300f2ff1
--- /dev/null
+++ b/tests/rustdoc/constant/generic-const-items.rs
@@ -0,0 +1,38 @@
+#![feature(generic_const_items)]
+#![allow(incomplete_features)]
+
+//@ has 'generic_const_items/constant.K.html'
+//@ has - '//*[@class="rust item-decl"]//code' \
+// "pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> \
+// where \
+//     String: From<T>;"
+pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> = None
+where
+    String: From<T>;
+
+//@ has generic_const_items/trait.Trait.html
+pub trait Trait<T: ?Sized> {
+    //@ has - '//*[@id="associatedconstant.C"]' \
+    // "const C<'a>: &'a T \
+    // where \
+    //     T: 'a + Eq"
+    const C<'a>: &'a T
+    where
+        T: 'a + Eq;
+}
+
+pub struct Implementor;
+
+//@ has generic_const_items/struct.Implementor.html
+//@ has - '//h3[@class="code-header"]' 'impl Trait<str> for Implementor'
+impl Trait<str> for Implementor {
+    //@ has - '//*[@id="associatedconstant.C"]' \
+    // "const C<'a>: &'a str = \"C\" \
+    // where \
+    //     str: 'a"
+    const C<'a>: &'a str = "C"
+    // In real code we could've left off this bound but adding it explicitly allows us to test if
+    // we render where-clauses on associated consts inside impl blocks correctly.
+    where
+        str: 'a;
+}
diff --git a/tests/rustdoc/constant/generic_const_exprs.rs b/tests/rustdoc/constant/generic_const_exprs.rs
new file mode 100644
index 00000000000..44f7bf5b24c
--- /dev/null
+++ b/tests/rustdoc/constant/generic_const_exprs.rs
@@ -0,0 +1,24 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/92859>.
+
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+#![crate_name = "foo"]
+
+//@ has 'foo/trait.Foo.html'
+
+pub trait Foo: Sized {
+    const WIDTH: usize;
+
+    fn arrayify(self) -> [Self; Self::WIDTH];
+}
+
+impl<T: Sized> Foo for T {
+    const WIDTH: usize = 1;
+
+    //@ has - '//*[@id="tymethod.arrayify"]/*[@class="code-header"]' \
+    // 'fn arrayify(self) -> [Self; Self::WIDTH]'
+    fn arrayify(self) -> [Self; Self::WIDTH] {
+        [self]
+    }
+}
diff --git a/tests/rustdoc/constant/glob-shadowing-const.rs b/tests/rustdoc/constant/glob-shadowing-const.rs
new file mode 100644
index 00000000000..fbc22dbccaa
--- /dev/null
+++ b/tests/rustdoc/constant/glob-shadowing-const.rs
@@ -0,0 +1,20 @@
+// https://github.com/rust-lang/rust/pull/83872#issuecomment-820101008
+#![crate_name="foo"]
+
+mod sub4 {
+    /// 0
+    pub const X: usize = 0;
+    pub mod inner {
+        pub use super::*;
+        /// 1
+        pub const X: usize = 1;
+    }
+}
+
+#[doc(inline)]
+pub use sub4::inner::*;
+
+//@ has 'foo/index.html'
+//@ has - '//dd' '1'
+//@ !has - '//dd' '0'
+fn main() { assert_eq!(X, 1); }
diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs
new file mode 100644
index 00000000000..e94c1ea5c61
--- /dev/null
+++ b/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs
@@ -0,0 +1,91 @@
+// Test that certain unevaluated constant expression arguments that are
+// deemed too verbose or complex and that may leak private or
+// `doc(hidden)` struct fields are not displayed in the documentation.
+//
+// Read the documentation of `rustdoc::clean::utils::print_const_expr`
+// for further details.
+#![feature(const_trait_impl, generic_const_exprs, adt_const_params, generic_const_items)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy;
+
+//@ has hide_complex_unevaluated_const_arguments/trait.Stage.html
+pub trait Stage {
+    // A helper constant that prevents const expressions containing it
+    // from getting fully evaluated since it doesn't have a body and
+    // thus is non-reducible. This allows us to specifically test the
+    // pretty-printing of *unevaluated* consts.
+    const ABSTRACT: usize;
+
+    // Currently considered "overly complex" by the `generic_const_exprs`
+    // feature. If / once this expression kind gets supported, this
+    // unevaluated const expression could leak the private struct field.
+    //
+    // FIXME: Once the line below compiles, make this a test that
+    //        ensures that the private field is not printed.
+    //
+    //const ARRAY0: [u8; Struct { private: () } + Self::ABSTRACT];
+
+    // This assoc. const could leak the private assoc. function `Struct::new`.
+    // Ensure that this does not happen.
+    //
+    //@ has - '//*[@id="associatedconstant.ARRAY1"]' \
+    //        'const ARRAY1: [u8; { _ }]'
+    const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]
+        where [(); Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]:;
+
+    //@ has - '//*[@id="associatedconstant.VERBOSE"]' \
+    //        'const VERBOSE: [u16; { _ }]'
+    const VERBOSE: [u16; compute("thing", 9 + 9) * Self::ABSTRACT]
+        where [(); compute("thing", 9 + 9) * Self::ABSTRACT]:;
+
+    // Check that we do not leak the private struct field contained within
+    // the path. The output could definitely be improved upon
+    // (e.g. printing sth. akin to `<Self as Helper<{ _ }>>::OUT`) but
+    // right now “safe is safe”.
+    //
+    //@ has - '//*[@id="associatedconstant.PATH"]' \
+    //        'const PATH: usize = _'
+    const PATH: usize = <Self as Helper<{ Struct { private: () } }>>::OUT;
+}
+
+const fn compute(input: &str, extra: usize) -> usize {
+    input.len() + extra
+}
+
+pub trait Helper<const S: Struct> {
+    const OUT: usize;
+}
+
+impl<const S: Struct, St: Stage + ?Sized> Helper<S> for St {
+    const OUT: usize = St::ABSTRACT;
+}
+
+// Currently in rustdoc, const arguments are not evaluated in this position
+// and therefore they fall under the realm of `print_const_expr`.
+// If rustdoc gets patched to evaluate const arguments, it is fine to replace
+// this test as long as one can ensure that private fields are not leaked!
+//
+//@ has hide_complex_unevaluated_const_arguments/trait.Sub.html \
+//      '//pre[@class="rust item-decl"]' \
+//      'pub trait Sub: Sup<{ _ }, { _ }> { }'
+pub trait Sub: Sup<{ 90 * 20 * 4 }, { Struct { private: () } }> {}
+
+pub trait Sup<const N: usize, const S: Struct> {}
+
+#[derive(ConstParamTy, PartialEq, Eq)]
+pub struct Struct { private: () }
+
+impl Struct {
+    const fn new() -> Self { Self { private: () } }
+    const fn do_something(self, x: usize) -> usize {
+        x
+    }
+}
+/* FIXME(const-trait): readd this
+impl const std::ops::Add<usize> for Struct {
+    type Output = usize;
+
+    fn add(self, _: usize) -> usize { 0 }
+}
+*/
diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs b/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs
new file mode 100644
index 00000000000..61ae8c801dd
--- /dev/null
+++ b/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs
@@ -0,0 +1,71 @@
+// Regression test for issue #97933.
+//
+// Test that certain unevaluated constant expressions that are
+// deemed too verbose or complex and that may leak private or
+// `doc(hidden)` struct fields are not displayed in the documentation.
+//
+// Read the documentation of `rustdoc::clean::utils::print_const_expr`
+// for further details.
+
+//@ has hide_complex_unevaluated_consts/trait.Container.html
+pub trait Container {
+    // A helper constant that prevents const expressions containing it
+    // from getting fully evaluated since it doesn't have a body and
+    // thus is non-reducible. This allows us to specifically test the
+    // pretty-printing of *unevaluated* consts.
+    const ABSTRACT: i32;
+
+    // Ensure that the private field does not get leaked:
+    //
+    //@ has - '//*[@id="associatedconstant.STRUCT0"]' \
+    //        'const STRUCT0: Struct = _'
+    const STRUCT0: Struct = Struct { private: () };
+
+    //@ has - '//*[@id="associatedconstant.STRUCT1"]' \
+    //        'const STRUCT1: (Struct,) = _'
+    const STRUCT1: (Struct,) = (Struct{private: /**/()},);
+
+    // Although the struct field is public here, check that it is not
+    // displayed. In a future version of rustdoc, we definitely want to
+    // show it. However for the time being, the printing logic is a bit
+    // conservative.
+    //
+    //@ has - '//*[@id="associatedconstant.STRUCT2"]' \
+    //        'const STRUCT2: Record = _'
+    const STRUCT2: Record = Record { public: 5 };
+
+    // Test that we do not show the incredibly verbose match expr:
+    //
+    //@ has - '//*[@id="associatedconstant.MATCH0"]' \
+    //        'const MATCH0: i32 = _'
+    const MATCH0: i32 = match 234 {
+        0 => 1,
+        _ => Self::ABSTRACT,
+    };
+
+    //@ has - '//*[@id="associatedconstant.MATCH1"]' \
+    //        'const MATCH1: bool = _'
+    const MATCH1: bool = match Self::ABSTRACT {
+        _ => true,
+    };
+
+    // Check that we hide complex (arithmetic) operations.
+    // In this case, it is a bit unfortunate since the expression
+    // is not *that* verbose and it might be quite useful to the reader.
+    //
+    // However in general, the expression might be quite large and
+    // contain match expressions and structs with private fields.
+    // We would need to recurse over the whole expression and even more
+    // importantly respect operator precedence when pretty-printing
+    // the potentially partially censored expression.
+    // For now, the implementation is quite simple and the choices
+    // rather conservative.
+    //
+    //@ has - '//*[@id="associatedconstant.ARITH_OPS"]' \
+    //        'const ARITH_OPS: i32 = _'
+    const ARITH_OPS: i32 = Self::ABSTRACT * 2 + 1;
+}
+
+pub struct Struct { private: () }
+
+pub struct Record { pub public: i32 }
diff --git a/tests/rustdoc/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs
new file mode 100644
index 00000000000..1bcdfac7342
--- /dev/null
+++ b/tests/rustdoc/constant/ice-associated-const-equality-105952.rs
@@ -0,0 +1,15 @@
+// https://github.com/rust-lang/rust/issues/105952
+#![crate_name = "foo"]
+
+#![feature(associated_const_equality)]
+pub enum ParseMode {
+    Raw,
+}
+pub trait Parse {
+    const PARSE_MODE: ParseMode;
+}
+pub trait RenderRaw {}
+
+//@ hasraw foo/trait.RenderRaw.html 'impl'
+//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw'
+impl<T: Parse<PARSE_MODE = { ParseMode::Raw }>> RenderRaw for T {}
diff --git a/tests/rustdoc/constant/legacy-const-generic.rs b/tests/rustdoc/constant/legacy-const-generic.rs
new file mode 100644
index 00000000000..41df535f3e0
--- /dev/null
+++ b/tests/rustdoc/constant/legacy-const-generic.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+#![feature(rustc_attrs)]
+
+//@ has 'foo/fn.foo.html'
+//@ has - '//pre[@class="rust item-decl"]' 'fn foo(x: usize, const Y: usize, z: usize) -> [usize; 3]'
+#[rustc_legacy_const_generics(1)]
+pub fn foo<const Y: usize>(x: usize, z: usize) -> [usize; 3] {
+    [x, Y, z]
+}
+
+//@ has 'foo/fn.bar.html'
+//@ has - '//pre[@class="rust item-decl"]' 'fn bar(x: usize, const Y: usize, const Z: usize) -> [usize; 3]'
+#[rustc_legacy_const_generics(1, 2)]
+pub fn bar<const Y: usize, const Z: usize>(x: usize) -> [usize; 3] {
+    [x, Y, z]
+}
diff --git a/tests/rustdoc/constant/link-assoc-const.rs b/tests/rustdoc/constant/link-assoc-const.rs
new file mode 100644
index 00000000000..56b82fb2d39
--- /dev/null
+++ b/tests/rustdoc/constant/link-assoc-const.rs
@@ -0,0 +1,16 @@
+#![crate_name = "foo"]
+
+//@ has foo/index.html '//a[@href="foo/constant.FIRSTCONST.html"]' 'foo::FIRSTCONST'
+//@ has foo/index.html '//a[@href="struct.Bar.html#associatedconstant.CONST"]' 'Bar::CONST'
+
+//! We have here [`foo::FIRSTCONST`] and [`Bar::CONST`].
+
+pub mod foo {
+    pub const FIRSTCONST: u32 = 42;
+}
+
+pub struct Bar;
+
+impl Bar {
+    pub const CONST: u32 = 42;
+}
diff --git a/tests/rustdoc/constant/redirect-const.rs b/tests/rustdoc/constant/redirect-const.rs
new file mode 100644
index 00000000000..e636a915f30
--- /dev/null
+++ b/tests/rustdoc/constant/redirect-const.rs
@@ -0,0 +1,13 @@
+#![crate_name="foo"]
+
+pub use hidden::STATIC_FOO;
+pub use hidden::CONST_FOO;
+
+mod hidden {
+    //@ has foo/hidden/static.STATIC_FOO.html
+    //@ has - '//p/a' '../../foo/static.STATIC_FOO.html'
+    pub static STATIC_FOO: u64 = 0;
+    //@ has foo/hidden/constant.CONST_FOO.html
+    //@ has - '//p/a' '../../foo/constant.CONST_FOO.html'
+    pub const CONST_FOO: u64 = 0;
+}
diff --git a/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs
new file mode 100644
index 00000000000..8a86e3e5e97
--- /dev/null
+++ b/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs
@@ -0,0 +1,73 @@
+// Test that we do not currently display `~const` in rustdoc
+// as that syntax is currently provisional; `~const Destruct` 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.
+//
+// FIXME(const_trait_impl) add `const_trait` to `Fn` so we use `~const`
+// FIXME(const_trait_impl) restore `const_trait` to `Destruct`
+#![feature(const_trait_impl)]
+#![crate_name = "foo"]
+
+use std::marker::Destruct;
+
+pub struct S<T>(T);
+
+//@ !has foo/trait.Tr.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const'
+//@ has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn'
+//@ !has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' '~const'
+//@ has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Fn'
+#[const_trait]
+pub trait Tr<T> {
+    //@ !has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const'
+    //@ has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn'
+    //@ !has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
+    //@ has - '//section[@id="method.a"]/h4[@class="code-header"]/div[@class="where"]' ': Fn'
+    fn a<A: /* ~const */ Fn() /* + ~const Destruct */>()
+    where
+        Option<A>: /* ~const */ Fn() /* + ~const Destruct */,
+    {
+    }
+}
+
+//@ has - '//section[@id="impl-Tr%3CT%3E-for-T"]' ''
+//@ !has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]' '~const'
+//@ has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn'
+//@ !has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const'
+//@ has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/div[@class="where"]' ': Fn'
+impl<T: /* ~const */ Fn() /* + ~const Destruct */> const Tr<T> for T
+where
+    Option<T>: /* ~const */ Fn() /* + ~const Destruct */,
+{
+    fn a<A: /* ~const */ Fn() /* + ~const Destruct */>()
+    where
+        Option<A>: /* ~const */ Fn() /* + ~const Destruct */,
+    {
+    }
+}
+
+//@ !has foo/fn.foo.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const'
+//@ has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn'
+//@ !has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' '~const'
+//@ has - '//pre[@class="rust item-decl"]/code/div[@class="where"]' ': Fn'
+pub const fn foo<F: /* ~const */ Fn() /* + ~const Destruct */>()
+where
+    Option<F>: /* ~const */ Fn() /* + ~const Destruct */,
+{
+    F::a()
+}
+
+impl<T> S<T> {
+    //@ !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"]' 'Fn'
+    //@ !has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
+    //@ has - '//section[@id="method.foo"]/h4[@class="code-header"]/div[@class="where"]' ': Fn'
+    pub const fn foo<B, C: /* ~const */ Fn() /* + ~const Destruct */>()
+    where
+        B: /* ~const */ Fn() /* + ~const Destruct */,
+    {
+        B::a()
+    }
+}
diff --git a/tests/rustdoc/constant/show-const-contents.rs b/tests/rustdoc/constant/show-const-contents.rs
new file mode 100644
index 00000000000..6d2701693ce
--- /dev/null
+++ b/tests/rustdoc/constant/show-const-contents.rs
@@ -0,0 +1,68 @@
+// Test that the contents of constants are displayed as part of the
+// documentation.
+
+//@ hasraw show_const_contents/constant.CONST_S.html 'show this'
+//@ !hasraw show_const_contents/constant.CONST_S.html '; //'
+pub const CONST_S: &'static str = "show this";
+
+//@ hasraw show_const_contents/constant.CONST_I32.html '= 42;'
+//@ !hasraw show_const_contents/constant.CONST_I32.html '; //'
+pub const CONST_I32: i32 = 42;
+
+//@ hasraw show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
+//@ !hasraw show_const_contents/constant.CONST_I32_HEX.html '; //'
+pub const CONST_I32_HEX: i32 = 0x42;
+
+//@ hasraw show_const_contents/constant.CONST_NEG_I32.html '= -42;'
+//@ !hasraw show_const_contents/constant.CONST_NEG_I32.html '; //'
+pub const CONST_NEG_I32: i32 = -42;
+
+//@ hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
+//@ !hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
+pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
+
+//@ hasraw show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32'
+pub const CONST_CALC_I32: i32 = 42 + 1;
+
+//@ !hasraw show_const_contents/constant.CONST_REF_I32.html '= &42;'
+//@ !hasraw show_const_contents/constant.CONST_REF_I32.html '; //'
+pub const CONST_REF_I32: &'static i32 = &42;
+
+//@ hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32'
+pub const CONST_I32_MAX: i32 = i32::MAX;
+
+//@ !hasraw show_const_contents/constant.UNIT.html '= ();'
+//@ !hasraw show_const_contents/constant.UNIT.html '; //'
+pub const UNIT: () = ();
+
+pub struct MyType(i32);
+
+//@ !hasraw show_const_contents/constant.MY_TYPE.html '= MyType(42);'
+//@ !hasraw show_const_contents/constant.MY_TYPE.html '; //'
+pub const MY_TYPE: MyType = MyType(42);
+
+pub struct MyTypeWithStr(&'static str);
+
+//@ !hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
+//@ !hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
+pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");
+
+//@ hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288_f32;'
+//@ hasraw show_const_contents/constant.PI.html '; // 3.14159274f32'
+pub use std::f32::consts::PI;
+
+//@ hasraw show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
+#[allow(deprecated, deprecated_in_future)]
+pub use std::i32::MAX;
+
+macro_rules! int_module {
+    ($T:ident) => (
+        pub const MIN: $T = $T::MIN;
+    )
+}
+
+//@ hasraw show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16'
+int_module!(i16);
+
+//@ has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
+pub const ESCAPE: &str = r#"<script>alert("ESCAPE");</script>"#;