about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-19 05:14:06 +0000
committerbors <bors@rust-lang.org>2024-11-19 05:14:06 +0000
commite6c1e14e5d487a90abeb5ba4dccc608521bbfb54 (patch)
treeb9781aa2b8d278e3261e7de668008705b5dd4299
parent5926e82dd1eae211c6e2ffe446de54df04798e89 (diff)
parent56747f30b4d601d1d94c8dc32748e072bcb11573 (diff)
downloadrust-e6c1e14e5d487a90abeb5ba4dccc608521bbfb54.tar.gz
rust-e6c1e14e5d487a90abeb5ba4dccc608521bbfb54.zip
Auto merge of #133193 - fmease:rollup-v38ayvk, r=fmease
Rollup of 9 pull requests

Successful merges:

 - #132758 (Improve `{BTreeMap,HashMap}::get_key_value` docs.)
 - #133180 ([rustdoc] Fix items with generics not having their jump to def link generated)
 - #133181 (Update books)
 - #133182 (const_panic: inline in bootstrap builds to avoid f16/f128 crashes)
 - #133185 (rustdoc-search: use smart binary search in bitmaps)
 - #133186 (Document s390x-unknown-linux targets)
 - #133187 (Add reference annotations for diagnostic attributes)
 - #133191 (rustdoc book: Move `--test-builder(--wrapper)?` docs to unstable section.)
 - #133192 (RELEASES.md: Don't document unstable `--test-build-wrapper`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--RELEASES.md7
-rw-r--r--library/alloc/src/collections/btree/map.rs46
-rw-r--r--library/core/src/panic.rs2
-rw-r--r--library/std/src/collections/hash/map.rs40
m---------src/doc/edition-guide0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/platform-support.md4
-rw-r--r--src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md113
-rw-r--r--src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md83
-rw-r--r--src/doc/rustdoc/src/command-line-arguments.md29
-rw-r--r--src/doc/rustdoc/src/unstable-features.md33
-rw-r--r--src/librustdoc/html/render/span_map.rs23
-rw-r--r--src/librustdoc/html/static/js/search.js65
-rw-r--r--tests/rustdoc/link-on-path-with-generics.rs14
-rw-r--r--tests/ui/diagnostic_namespace/deny_malformed_attribute.rs2
-rw-r--r--tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr4
-rw-r--r--tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs1
-rw-r--r--tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr36
-rw-r--r--tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs1
-rw-r--r--tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr4
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs1
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr54
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs (renamed from tests/ui/traits/custom-on-unimplemented-diagnostic.rs)2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr (renamed from tests/ui/traits/custom-on-unimplemented-diagnostic.stderr)8
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs4
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr74
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr54
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.rs1
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.stderr4
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr14
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs1
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr12
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr6
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs1
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr14
-rw-r--r--tests/ui/diagnostic_namespace/suggest_typos.rs1
-rw-r--r--tests/ui/diagnostic_namespace/suggest_typos.stderr8
-rw-r--r--tests/ui/traits/negative-bounds/on-unimplemented.rs2
-rw-r--r--tests/ui/traits/negative-bounds/on-unimplemented.stderr2
45 files changed, 570 insertions, 208 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 40ddba6dbc5..54465621b73 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -670,13 +670,6 @@ Cargo
 - [Support `target.<triple>.rustdocflags` officially](https://github.com/rust-lang/cargo/pull/13197/)
 - [Stabilize global cache data tracking](https://github.com/rust-lang/cargo/pull/13492/)
 
-<a id="1.78.0-Misc"></a>
-
-Misc
-----
-
-- [rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests](https://github.com/rust-lang/rust/pull/114651/)
-
 <a id="1.78.0-Compatibility-Notes"></a>
 
 Compatibility Notes
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 66353ccfa47..213924d1d02 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -677,7 +677,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
         }
     }
 
-    /// Returns the key-value pair corresponding to the supplied key.
+    /// Returns the key-value pair corresponding to the supplied key. This is
+    /// potentially useful:
+    /// - for key types where non-identical keys can be considered equal;
+    /// - for getting the `&K` stored key value from a borrowed `&Q` lookup key; or
+    /// - for getting a reference to a key with the same lifetime as the collection.
     ///
     /// The supplied key may be any borrowed form of the map's key type, but the ordering
     /// on the borrowed form *must* match the ordering on the key type.
@@ -685,12 +689,46 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// # Examples
     ///
     /// ```
+    /// use std::cmp::Ordering;
     /// use std::collections::BTreeMap;
     ///
+    /// #[derive(Clone, Copy, Debug)]
+    /// struct S {
+    ///     id: u32,
+    /// #   #[allow(unused)] // prevents a "field `name` is never read" error
+    ///     name: &'static str, // ignored by equality and ordering operations
+    /// }
+    ///
+    /// impl PartialEq for S {
+    ///     fn eq(&self, other: &S) -> bool {
+    ///         self.id == other.id
+    ///     }
+    /// }
+    ///
+    /// impl Eq for S {}
+    ///
+    /// impl PartialOrd for S {
+    ///     fn partial_cmp(&self, other: &S) -> Option<Ordering> {
+    ///         self.id.partial_cmp(&other.id)
+    ///     }
+    /// }
+    ///
+    /// impl Ord for S {
+    ///     fn cmp(&self, other: &S) -> Ordering {
+    ///         self.id.cmp(&other.id)
+    ///     }
+    /// }
+    ///
+    /// let j_a = S { id: 1, name: "Jessica" };
+    /// let j_b = S { id: 1, name: "Jess" };
+    /// let p = S { id: 2, name: "Paul" };
+    /// assert_eq!(j_a, j_b);
+    ///
     /// let mut map = BTreeMap::new();
-    /// map.insert(1, "a");
-    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
-    /// assert_eq!(map.get_key_value(&2), None);
+    /// map.insert(j_a, "Paris");
+    /// assert_eq!(map.get_key_value(&j_a), Some((&j_a, &"Paris")));
+    /// assert_eq!(map.get_key_value(&j_b), Some((&j_a, &"Paris"))); // the notable case
+    /// assert_eq!(map.get_key_value(&p), None);
     /// ```
     #[stable(feature = "map_get_key_value", since = "1.40.0")]
     pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index e702056f00a..179aadf0c28 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -215,7 +215,7 @@ pub macro const_panic {
                 #[noinline]
                 if const #[track_caller] #[inline] { // Inline this, to prevent codegen
                     $crate::panic!($const_msg)
-                } else #[track_caller] { // Do not inline this, it makes perf worse
+                } else #[track_caller] #[cfg_attr(bootstrap, inline)] { // Do not inline this, it makes perf worse
                     $crate::panic!($runtime_msg)
                 }
             )
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index ded4f404d78..24bbc2f32cf 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -880,7 +880,11 @@ where
         self.base.get(k)
     }
 
-    /// Returns the key-value pair corresponding to the supplied key.
+    /// Returns the key-value pair corresponding to the supplied key. This is
+    /// potentially useful:
+    /// - for key types where non-identical keys can be considered equal;
+    /// - for getting the `&K` stored key value from a borrowed `&Q` lookup key; or
+    /// - for getting a reference to a key with the same lifetime as the collection.
     ///
     /// The supplied key may be any borrowed form of the map's key type, but
     /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
@@ -890,11 +894,39 @@ where
     ///
     /// ```
     /// use std::collections::HashMap;
+    /// use std::hash::{Hash, Hasher};
+    ///
+    /// #[derive(Clone, Copy, Debug)]
+    /// struct S {
+    ///     id: u32,
+    /// #   #[allow(unused)] // prevents a "field `name` is never read" error
+    ///     name: &'static str, // ignored by equality and hashing operations
+    /// }
+    ///
+    /// impl PartialEq for S {
+    ///     fn eq(&self, other: &S) -> bool {
+    ///         self.id == other.id
+    ///     }
+    /// }
+    ///
+    /// impl Eq for S {}
+    ///
+    /// impl Hash for S {
+    ///     fn hash<H: Hasher>(&self, state: &mut H) {
+    ///         self.id.hash(state);
+    ///     }
+    /// }
+    ///
+    /// let j_a = S { id: 1, name: "Jessica" };
+    /// let j_b = S { id: 1, name: "Jess" };
+    /// let p = S { id: 2, name: "Paul" };
+    /// assert_eq!(j_a, j_b);
     ///
     /// let mut map = HashMap::new();
-    /// map.insert(1, "a");
-    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
-    /// assert_eq!(map.get_key_value(&2), None);
+    /// map.insert(j_a, "Paris");
+    /// assert_eq!(map.get_key_value(&j_a), Some((&j_a, &"Paris")));
+    /// assert_eq!(map.get_key_value(&j_b), Some((&j_a, &"Paris"))); // the notable case
+    /// assert_eq!(map.get_key_value(&p), None);
     /// ```
     #[inline]
     #[stable(feature = "map_get_key_value", since = "1.40.0")]
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 2d482e203eb6d6e353814cf1415c5f94e590b9e
+Subproject 915f9b319c2823f310430ecdecd86264a7870d7
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 456b904f791751892b01282fd2757904993c4c2
+Subproject eac89a3cbe6c4714e5029ae8b5a1c556fd4e8c4
diff --git a/src/doc/reference b/src/doc/reference
-Subproject da0f6dad767670da0e8cd5af8a7090db3272f62
+Subproject 41ccb0e6478305401dad92e8fd3d04a4304edb4
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 6a5accdaf10255882b1e6c59dfe5f1c79ac9548
+Subproject b679e71c2d66c6fe13e06b99ac61773b866213f
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 18f76ac6fe0..f3d8a4edd6c 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -72,6 +72,8 @@
     - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
     - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md)
     - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md)
+    - [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md)
+    - [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
     - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
     - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 500eaafb63f..243cb3b2fc8 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -99,7 +99,7 @@ target | notes
 `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
 [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29)
 [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3)
-`s390x-unknown-linux-gnu` | S390x Linux (kernel 3.2, glibc 2.17)
+[`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17)
 `x86_64-unknown-freebsd` | 64-bit FreeBSD
 `x86_64-unknown-illumos` | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
@@ -367,7 +367,7 @@ target | std | host | notes
 [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
 [`riscv64-linux-android`](platform-support/android.md) |   |   | RISC-V 64-bit Android
 [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
-`s390x-unknown-linux-musl` |  |  | S390x Linux (kernel 3.2, musl 1.2.3)
+[`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) |  |  | S390x Linux (kernel 3.2, musl 1.2.3)
 `sparc-unknown-linux-gnu` | ✓ |  | 32-bit SPARC Linux
 [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * |  | Bare 32-bit SPARC V7+
 [`sparc64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/sparc64
diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md
new file mode 100644
index 00000000000..60e06c404c0
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-gnu.md
@@ -0,0 +1,113 @@
+# `s390x-unknown-linux-gnu`
+
+**Tier: 2 (with Host Tools)**
+
+IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux.
+
+## Target maintainers
+
+- Ulrich Weigand, <ulrich.weigand@de.ibm.com>, [@uweigand](https://github.com/uweigand)
+- Josh Stone, <jistone@redhat.com>, [@cuviper](https://github.com/cuviper)
+
+## Requirements
+
+This target requires:
+
+* Linux Kernel version 3.2 or later
+* glibc 2.17 or later
+
+Code generated by the target uses the z/Architecture ISA assuming a minimum
+architecture level of z10 (Eighth Edition of the z/Architecture Principles
+of Operation), and is compliant with the s390x ELF ABI.
+
+Reference material:
+
+* [z/Architecture Principles of Operation][s390x-isa]
+* [z/Architecture ELF Application Binary Interface][s390x-abi]
+
+[s390x-isa]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf
+[s390x-abi]: https://github.com/IBM/s390x-abi
+
+## Building the target
+
+This target is distributed through `rustup`, and otherwise requires no
+special configuration.
+
+If you need to build your own Rust for some reason though, the target can be
+enabled in `config.toml`. For example:
+
+```toml
+[build]
+target = ["s390x-unknown-linux-gnu"]
+```
+
+## Building Rust programs
+
+On a s390x Linux host, the `s390x-unknown-linux-gnu` target should be
+automatically installed and used by default.
+
+On a non-s390x host, add the target:
+
+```bash
+rustup target add s390x-unknown-linux-gnu
+```
+
+Then cross compile crates with:
+
+```bash
+cargo build --target s390x-unknown-linux-gnu
+```
+
+## Testing
+
+There are no special requirements for testing and running the target.
+For testing cross builds on the host, please refer to the "Cross-compilation
+toolchains and C code" section below.
+
+## Cross-compilation toolchains and C code
+
+Rust code built using the target is compatible with C code compiled with
+GCC or Clang using the `s390x-unknown-linux-gnu` target triple (via either
+native or cross-compilation).
+
+On Ubuntu, a s390x cross-toolchain can be installed with:
+
+```bash
+apt install gcc-s390x-linux-gnu g++-s390x-linux-gnu libc6-dev-s390x-cross
+```
+
+Depending on your system, you may need to configure the target to use the GNU
+GCC linker. To use it, add the following to your `.cargo/config.toml`:
+
+```toml
+[target.s390x-unknown-linux-gnu]
+linker = "s390x-linux-gnu-gcc"
+```
+
+If your `s390x-linux-gnu-*` toolchain is not in your `PATH` you may need to
+configure additional settings:
+
+```toml
+[target.s390x-unknown-linux-gnu]
+# Adjust the paths to point at your toolchain
+cc = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-gcc"
+cxx = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-g++"
+ar = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-ar"
+ranlib = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-ranlib"
+linker = "/TOOLCHAIN_PATH/bin/s390x-linux-gnu-gcc"
+```
+
+To test cross compiled binaries on a non-s390x host, you can use
+[`qemu`](https://www.qemu.org/docs/master/system/target-s390x.html).
+On Ubuntu, a s390x emulator can be obtained with:
+
+```bash
+apt install qemu-system-s390x
+```
+
+Then, in `.cargo/config.toml` set the `runner`:
+
+```toml
+[target.s390x-unknown-linux-gnu]
+runner = "qemu-s390x-static -L /usr/s390x-linux-gnu"
+```
diff --git a/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md
new file mode 100644
index 00000000000..e00f8db7f8e
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/s390x-unknown-linux-musl.md
@@ -0,0 +1,83 @@
+# `s390x-unknown-linux-musl`
+
+**Tier: 3**
+
+IBM z/Architecture (s390x) targets (including IBM Z and LinuxONE) running Linux.
+
+## Target maintainers
+
+- Ulrich Weigand, <ulrich.weigand@de.ibm.com>, [@uweigand](https://github.com/uweigand)
+
+## Requirements
+
+This target requires:
+
+* Linux Kernel version 3.2 or later
+* musl 1.2.3 or later
+
+Code generated by the target uses the z/Architecture ISA assuming a minimum
+architecture level of z10 (Eighth Edition of the z/Architecture Principles
+of Operation), and is compliant with the s390x ELF ABI.
+
+Reference material:
+
+* [z/Architecture Principles of Operation][s390x-isa]
+* [z/Architecture ELF Application Binary Interface][s390x-abi]
+
+[s390x-isa]: https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdf
+[s390x-abi]: https://github.com/IBM/s390x-abi
+
+## Building the target
+
+Because it is Tier 3, Rust does not yet ship pre-compiled artifacts for this
+target.
+
+Therefore, you can build Rust with support for the target by adding it to the
+target list in `config.toml`, a sample configuration is shown below.
+
+```toml
+[build]
+target = ["s390x-unknown-linux-musl"]
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will first need to build Rust with the target enabled (see
+"Building the target" above).
+
+## Testing
+
+There are no special requirements for testing and running the target.
+For testing cross builds on the host, please refer to the "Cross-compilation
+toolchains and C code" section below.
+
+## Cross-compilation toolchains and C code
+
+Rust code built using the target is compatible with C code compiled with
+GCC or Clang using the `s390x-unknown-linux-musl` target triple (via either
+native or cross-compilation).
+
+Depending on your system, you may need to configure the target to use the GNU
+GCC linker. To use it, add the following to your `.cargo/config.toml`:
+
+```toml
+[target.s390x-unknown-linux-musl]
+linker = "s390x-linux-musl-gcc"
+```
+
+If your `s390x-linux-musl-*` toolchain is not in your `PATH` you may need to
+configure additional settings:
+
+```toml
+[target.s390x-unknown-linux-musl]
+# Adjust the paths to point at your toolchain
+cc = "/TOOLCHAIN_PATH/bin/s390x-linux-musl-gcc"
+cxx = "/TOOLCHAIN_PATH/bin/s390x-linux-musl-g++"
+ar = "/TOOLCHAIN_PATH/bin/s390x-linux-musl-ar"
+ranlib = "/TOOLCHAIN_PATH/bin/s390x-linux-musl-ranlib"
+linker = "/TOOLCHAIN_PATH/bin/s390x-linux-musl-gcc"
+```
+
+To test cross compiled binaries on a non-s390x host, you can use
+[`qemu`](https://www.qemu.org/docs/master/system/target-s390x.html).
diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md
index f8fb5284472..1af5e2b0e1d 100644
--- a/src/doc/rustdoc/src/command-line-arguments.md
+++ b/src/doc/rustdoc/src/command-line-arguments.md
@@ -447,32 +447,3 @@ This flag is **deprecated** and **has no effect**.
 Rustdoc only supports Rust source code and Markdown input formats. If the
 file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
 Otherwise, it assumes that the input file is Rust.
-
-## `--test-builder`: `rustc`-like program to build tests
-
-Using this flag looks like this:
-
-```bash
-$ rustdoc --test-builder /path/to/rustc src/lib.rs
-```
-
-Rustdoc will use the provided program to compile tests instead of the default `rustc` program from
-the sysroot.
-
-## `--test-builder-wrapper`: wrap calls to the test builder
-
-Using this flag looks like this:
-
-```bash
-$ rustdoc --test-builder-wrapper /path/to/rustc-wrapper src/lib.rs
-$ rustdoc \
-    --test-builder-wrapper rustc-wrapper1 \
-    --test-builder-wrapper rustc-wrapper2 \
-    --test-builder rustc \
-    src/lib.rs
-```
-
-Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper program.
-The first argument to the program will be the test builder program.
-
-This flag can be passed multiple times to nest wrappers.
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index ebbe141b6f5..e9524c0b78d 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -627,3 +627,36 @@ add the `--scrape-tests` flag.
 
 This flag enables the generation of links in the source code pages which allow the reader
 to jump to a type definition.
+
+### `--test-builder`: `rustc`-like program to build tests
+
+ * Tracking issue: [#102981](https://github.com/rust-lang/rust/issues/102981)
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc --test-builder /path/to/rustc src/lib.rs
+```
+
+Rustdoc will use the provided program to compile tests instead of the default `rustc` program from
+the sysroot.
+
+### `--test-builder-wrapper`: wrap calls to the test builder
+
+ * Tracking issue: [#102981](https://github.com/rust-lang/rust/issues/102981)
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc -Zunstable-options --test-builder-wrapper /path/to/rustc-wrapper src/lib.rs
+$ rustdoc -Zunstable-options \
+    --test-builder-wrapper rustc-wrapper1 \
+    --test-builder-wrapper rustc-wrapper2 \
+    --test-builder rustc \
+    src/lib.rs
+```
+
+Similar to cargo `build.rustc-wrapper` option, this flag takes a `rustc` wrapper program.
+The first argument to the program will be the test builder program.
+
+This flag can be passed multiple times to nest wrappers.
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index b314b060368..d4cca562d6c 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -36,7 +36,7 @@ pub(crate) enum LinkFromSrc {
 /// It returns the `krate`, the source code files and the `span` correspondence map.
 ///
 /// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't
-/// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
+/// need the `span` context later on, only their position, so instead of keeping a whole `Span`, we
 /// only keep the `lo` and `hi`.
 pub(crate) fn collect_spans_and_sources(
     tcx: TyCtxt<'_>,
@@ -45,9 +45,9 @@ pub(crate) fn collect_spans_and_sources(
     include_sources: bool,
     generate_link_to_definition: bool,
 ) -> (FxIndexMap<PathBuf, String>, FxHashMap<Span, LinkFromSrc>) {
-    let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
-
     if include_sources {
+        let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
+
         if generate_link_to_definition {
             tcx.hir().walk_toplevel_module(&mut visitor);
         }
@@ -76,7 +76,22 @@ impl<'tcx> SpanMapVisitor<'tcx> {
                 } else {
                     LinkFromSrc::External(def_id)
                 };
-                self.matches.insert(path.span, link);
+                // In case the path ends with generics, we remove them from the span.
+                let span = path
+                    .segments
+                    .last()
+                    .map(|last| {
+                        // In `use` statements, the included item is not in the path segments.
+                        // However, it doesn't matter because you can't have generics on `use`
+                        // statements.
+                        if path.span.contains(last.ident.span) {
+                            path.span.with_hi(last.ident.span.hi())
+                        } else {
+                            path.span
+                        }
+                    })
+                    .unwrap_or(path.span);
+                self.matches.insert(span, link);
             }
             Res::Local(_) => {
                 if let Some(span) = self.tcx.hir().res_span(path.res) {
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index c1a021e9f8d..9e5cf497211 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -988,6 +988,12 @@ class VlqHexDecoder {
 }
 class RoaringBitmap {
     constructor(str) {
+        // https://github.com/RoaringBitmap/RoaringFormatSpec
+        //
+        // Roaring bitmaps are used for flags that can be kept in their
+        // compressed form, even when loaded into memory. This decoder
+        // turns the containers into objects, but uses byte array
+        // slices of the original format for the data payload.
         const strdecoded = atob(str);
         const u8array = new Uint8Array(strdecoded.length);
         for (let j = 0; j < strdecoded.length; ++j) {
@@ -1053,9 +1059,24 @@ class RoaringBitmap {
     contains(keyvalue) {
         const key = keyvalue >> 16;
         const value = keyvalue & 0xFFFF;
-        for (let i = 0; i < this.keys.length; ++i) {
-            if (this.keys[i] === key) {
-                return this.containers[i].contains(value);
+        // Binary search algorithm copied from
+        // https://en.wikipedia.org/wiki/Binary_search#Procedure
+        //
+        // Format is required by specification to be sorted.
+        // Because keys are 16 bits and unique, length can't be
+        // bigger than 2**16, and because we have 32 bits of safe int,
+        // left + right can't overflow.
+        let left = 0;
+        let right = this.keys.length - 1;
+        while (left <= right) {
+            const mid = Math.floor((left + right) / 2);
+            const x = this.keys[mid];
+            if (x < key) {
+                left = mid + 1;
+            } else if (x > key) {
+                right = mid - 1;
+            } else {
+                return this.containers[mid].contains(value);
             }
         }
         return false;
@@ -1068,11 +1089,23 @@ class RoaringBitmapRun {
         this.array = array;
     }
     contains(value) {
-        const l = this.runcount * 4;
-        for (let i = 0; i < l; i += 4) {
+        // Binary search algorithm copied from
+        // https://en.wikipedia.org/wiki/Binary_search#Procedure
+        //
+        // Since runcount is stored as 16 bits, left + right
+        // can't overflow.
+        let left = 0;
+        let right = this.runcount - 1;
+        while (left <= right) {
+            const mid = Math.floor((left + right) / 2);
+            const i = mid * 4;
             const start = this.array[i] | (this.array[i + 1] << 8);
             const lenm1 = this.array[i + 2] | (this.array[i + 3] << 8);
-            if (value >= start && value <= (start + lenm1)) {
+            if ((start + lenm1) < value) {
+                left = mid + 1;
+            } else if (start > value) {
+                right = mid - 1;
+            } else {
                 return true;
             }
         }
@@ -1085,10 +1118,22 @@ class RoaringBitmapArray {
         this.array = array;
     }
     contains(value) {
-        const l = this.cardinality * 2;
-        for (let i = 0; i < l; i += 2) {
-            const start = this.array[i] | (this.array[i + 1] << 8);
-            if (value === start) {
+        // Binary search algorithm copied from
+        // https://en.wikipedia.org/wiki/Binary_search#Procedure
+        //
+        // Since cardinality can't be higher than 4096, left + right
+        // cannot overflow.
+        let left = 0;
+        let right = this.cardinality - 1;
+        while (left <= right) {
+            const mid = Math.floor((left + right) / 2);
+            const i = mid * 2;
+            const x = this.array[i] | (this.array[i + 1] << 8);
+            if (x < value) {
+                left = mid + 1;
+            } else if (x > value) {
+                right = mid - 1;
+            } else {
                 return true;
             }
         }
diff --git a/tests/rustdoc/link-on-path-with-generics.rs b/tests/rustdoc/link-on-path-with-generics.rs
new file mode 100644
index 00000000000..22ba36c9f15
--- /dev/null
+++ b/tests/rustdoc/link-on-path-with-generics.rs
@@ -0,0 +1,14 @@
+// This test ensures that paths with generics still get their link to their definition
+// correctly generated.
+
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+#![crate_name = "foo"]
+
+//@ has 'src/foo/link-on-path-with-generics.rs.html'
+
+pub struct Soyo<T>(T);
+pub struct Saya;
+
+//@ has - '//pre[@class="rust"]//a[@href="#9"]' 'Soyo'
+//@ has - '//pre[@class="rust"]//a[@href="#10"]' 'Saya'
+pub fn bar<T>(s: Soyo<T>, x: Saya) {}
diff --git a/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs b/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs
index 1d946a14aff..a46c856d38e 100644
--- a/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs
+++ b/tests/ui/diagnostic_namespace/deny_malformed_attribute.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.namespace.unknown-invalid-syntax
+
 #![deny(unknown_or_malformed_diagnostic_attributes)]
 
 #[diagnostic::unknown_attribute]
diff --git a/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr
index a646d3613de..32be9db5317 100644
--- a/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr
+++ b/tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr
@@ -1,11 +1,11 @@
 error: unknown diagnostic attribute
-  --> $DIR/deny_malformed_attribute.rs:3:15
+  --> $DIR/deny_malformed_attribute.rs:5:15
    |
 LL | #[diagnostic::unknown_attribute]
    |               ^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/deny_malformed_attribute.rs:1:9
+  --> $DIR/deny_malformed_attribute.rs:3:9
    |
 LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs
index 8b7467a17d0..b90dd0c7c94 100644
--- a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs
+++ b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.rs
@@ -1,5 +1,6 @@
 //@ edition:2021
 //@ aux-build:bad_on_unimplemented.rs
+//@ reference: attributes.diagnostic.on_unimplemented.syntax
 
 // Do not ICE when encountering a malformed `#[diagnostic::on_unimplemented]` annotation in a
 // dependency when incorrectly used (#124651).
diff --git a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr
index c3e56550b70..f1258ad6b9a 100644
--- a/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr
+++ b/tests/ui/diagnostic_namespace/malformed_foreign_on_unimplemented.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): bad_on_unimplemented::MissingAttr` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:22:18
+  --> $DIR/malformed_foreign_on_unimplemented.rs:23:18
    |
 LL |     missing_attr(());
    |     ------------ ^^ the trait `bad_on_unimplemented::MissingAttr` is not implemented for `()`
@@ -7,13 +7,13 @@ LL |     missing_attr(());
    |     required by a bound introduced by this call
    |
 note: required by a bound in `missing_attr`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:11:20
+  --> $DIR/malformed_foreign_on_unimplemented.rs:12:20
    |
 LL | fn missing_attr<T: MissingAttr>(_: T) {}
    |                    ^^^^^^^^^^^ required by this bound in `missing_attr`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::DuplicateAttr` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:23:20
+  --> $DIR/malformed_foreign_on_unimplemented.rs:24:20
    |
 LL |     duplicate_attr(());
    |     -------------- ^^ a
@@ -22,13 +22,13 @@ LL |     duplicate_attr(());
    |
    = help: the trait `bad_on_unimplemented::DuplicateAttr` is not implemented for `()`
 note: required by a bound in `duplicate_attr`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:12:22
+  --> $DIR/malformed_foreign_on_unimplemented.rs:13:22
    |
 LL | fn duplicate_attr<T: DuplicateAttr>(_: T) {}
    |                      ^^^^^^^^^^^^^ required by this bound in `duplicate_attr`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::NotMetaList` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:24:19
+  --> $DIR/malformed_foreign_on_unimplemented.rs:25:19
    |
 LL |     not_meta_list(());
    |     ------------- ^^ the trait `bad_on_unimplemented::NotMetaList` is not implemented for `()`
@@ -36,13 +36,13 @@ LL |     not_meta_list(());
    |     required by a bound introduced by this call
    |
 note: required by a bound in `not_meta_list`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:13:21
+  --> $DIR/malformed_foreign_on_unimplemented.rs:14:21
    |
 LL | fn not_meta_list<T: NotMetaList>(_: T) {}
    |                     ^^^^^^^^^^^ required by this bound in `not_meta_list`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::Empty` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:25:11
+  --> $DIR/malformed_foreign_on_unimplemented.rs:26:11
    |
 LL |     empty(());
    |     ----- ^^ the trait `bad_on_unimplemented::Empty` is not implemented for `()`
@@ -50,13 +50,13 @@ LL |     empty(());
    |     required by a bound introduced by this call
    |
 note: required by a bound in `empty`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:14:13
+  --> $DIR/malformed_foreign_on_unimplemented.rs:15:13
    |
 LL | fn empty<T: Empty>(_: T) {}
    |             ^^^^^ required by this bound in `empty`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::WrongDelim` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:26:17
+  --> $DIR/malformed_foreign_on_unimplemented.rs:27:17
    |
 LL |     wrong_delim(());
    |     ----------- ^^ the trait `bad_on_unimplemented::WrongDelim` is not implemented for `()`
@@ -64,13 +64,13 @@ LL |     wrong_delim(());
    |     required by a bound introduced by this call
    |
 note: required by a bound in `wrong_delim`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:15:19
+  --> $DIR/malformed_foreign_on_unimplemented.rs:16:19
    |
 LL | fn wrong_delim<T: WrongDelim>(_: T) {}
    |                   ^^^^^^^^^^ required by this bound in `wrong_delim`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::BadFormatter<()>` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:27:19
+  --> $DIR/malformed_foreign_on_unimplemented.rs:28:19
    |
 LL |     bad_formatter(());
    |     ------------- ^^ ()
@@ -79,13 +79,13 @@ LL |     bad_formatter(());
    |
    = help: the trait `bad_on_unimplemented::BadFormatter<()>` is not implemented for `()`
 note: required by a bound in `bad_formatter`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:16:21
+  --> $DIR/malformed_foreign_on_unimplemented.rs:17:21
    |
 LL | fn bad_formatter<T: BadFormatter<()>>(_: T) {}
    |                     ^^^^^^^^^^^^^^^^ required by this bound in `bad_formatter`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::NoImplicitArgs` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:28:22
+  --> $DIR/malformed_foreign_on_unimplemented.rs:29:22
    |
 LL |     no_implicit_args(());
    |     ---------------- ^^ test {}
@@ -94,13 +94,13 @@ LL |     no_implicit_args(());
    |
    = help: the trait `bad_on_unimplemented::NoImplicitArgs` is not implemented for `()`
 note: required by a bound in `no_implicit_args`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:17:24
+  --> $DIR/malformed_foreign_on_unimplemented.rs:18:24
    |
 LL | fn no_implicit_args<T: NoImplicitArgs>(_: T) {}
    |                        ^^^^^^^^^^^^^^ required by this bound in `no_implicit_args`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::MissingArg` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:29:17
+  --> $DIR/malformed_foreign_on_unimplemented.rs:30:17
    |
 LL |     missing_arg(());
    |     ----------- ^^ {missing}
@@ -109,13 +109,13 @@ LL |     missing_arg(());
    |
    = help: the trait `bad_on_unimplemented::MissingArg` is not implemented for `()`
 note: required by a bound in `missing_arg`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:18:19
+  --> $DIR/malformed_foreign_on_unimplemented.rs:19:19
    |
 LL | fn missing_arg<T: MissingArg>(_: T) {}
    |                   ^^^^^^^^^^ required by this bound in `missing_arg`
 
 error[E0277]: the trait bound `(): bad_on_unimplemented::BadArg` is not satisfied
-  --> $DIR/malformed_foreign_on_unimplemented.rs:30:13
+  --> $DIR/malformed_foreign_on_unimplemented.rs:31:13
    |
 LL |     bad_arg(());
    |     ------- ^^ {_}
@@ -124,7 +124,7 @@ LL |     bad_arg(());
    |
    = help: the trait `bad_on_unimplemented::BadArg` is not implemented for `()`
 note: required by a bound in `bad_arg`
-  --> $DIR/malformed_foreign_on_unimplemented.rs:19:15
+  --> $DIR/malformed_foreign_on_unimplemented.rs:20:15
    |
 LL | fn bad_arg<T: BadArg>(_: T) {}
    |               ^^^^^^ required by this bound in `bad_arg`
diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
index f6957b1448d..02c1352482c 100644
--- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
+++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
@@ -1,4 +1,5 @@
 //@ check-pass
+//@ reference: attributes.diagnostic.namespace.unknown-invalid-syntax
 #[diagnostic::non_existing_attribute]
 //~^WARN unknown diagnostic attribute
 pub trait Bar {
diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
index c073ec9b103..753077b365e 100644
--- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
+++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
@@ -1,5 +1,5 @@
 warning: unknown diagnostic attribute
-  --> $DIR/non_existing_attributes_accepted.rs:2:15
+  --> $DIR/non_existing_attributes_accepted.rs:3:15
    |
 LL | #[diagnostic::non_existing_attribute]
    |               ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::non_existing_attribute]
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: unknown diagnostic attribute
-  --> $DIR/non_existing_attributes_accepted.rs:7:15
+  --> $DIR/non_existing_attributes_accepted.rs:8:15
    |
 LL | #[diagnostic::non_existing_attribute(with_option = "foo")]
    |               ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
index 3ca58b28181..44f269eb967 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs
@@ -1,3 +1,4 @@
+//@ reference: attributes.diagnostic.on_unimplemented.invalid-string
 #[diagnostic::on_unimplemented(message = "{{Test } thing")]
 //~^WARN unmatched `}` found
 //~|WARN unmatched `}` found
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
index b4ed06cb63d..7fd51c7527f 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr
@@ -1,5 +1,5 @@
 warning: unmatched `}` found
-  --> $DIR/broken_format.rs:1:32
+  --> $DIR/broken_format.rs:2:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: positional format arguments are not allowed here
-  --> $DIR/broken_format.rs:6:32
+  --> $DIR/broken_format.rs:7:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {}")]
    |                                ^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {}")]
    = help: only named format arguments with the name of one of the generic types are allowed in this context
 
 warning: positional format arguments are not allowed here
-  --> $DIR/broken_format.rs:11:32
+  --> $DIR/broken_format.rs:12:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
    = help: only named format arguments with the name of one of the generic types are allowed in this context
 
 warning: invalid format specifier
-  --> $DIR/broken_format.rs:16:32
+  --> $DIR/broken_format.rs:17:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -31,19 +31,19 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
    = help: no format specifier are supported in this position
 
 warning: expected `}`, found `!`
-  --> $DIR/broken_format.rs:21:32
+  --> $DIR/broken_format.rs:22:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unmatched `}` found
-  --> $DIR/broken_format.rs:21:32
+  --> $DIR/broken_format.rs:22:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unmatched `}` found
-  --> $DIR/broken_format.rs:1:32
+  --> $DIR/broken_format.rs:2:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -51,7 +51,7 @@ LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: {{Test } thing
-  --> $DIR/broken_format.rs:35:13
+  --> $DIR/broken_format.rs:36:13
    |
 LL |     check_1(());
    |     ------- ^^ the trait `ImportantTrait1` is not implemented for `()`
@@ -59,18 +59,18 @@ LL |     check_1(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/broken_format.rs:4:1
+  --> $DIR/broken_format.rs:5:1
    |
 LL | trait ImportantTrait1 {}
    | ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check_1`
-  --> $DIR/broken_format.rs:28:20
+  --> $DIR/broken_format.rs:29:20
    |
 LL | fn check_1(_: impl ImportantTrait1) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_1`
 
 warning: positional format arguments are not allowed here
-  --> $DIR/broken_format.rs:6:32
+  --> $DIR/broken_format.rs:7:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {}")]
    |                                ^^^^^^^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Test {}
-  --> $DIR/broken_format.rs:37:13
+  --> $DIR/broken_format.rs:38:13
    |
 LL |     check_2(());
    |     ------- ^^ the trait `ImportantTrait2` is not implemented for `()`
@@ -87,18 +87,18 @@ LL |     check_2(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/broken_format.rs:9:1
+  --> $DIR/broken_format.rs:10:1
    |
 LL | trait ImportantTrait2 {}
    | ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check_2`
-  --> $DIR/broken_format.rs:29:20
+  --> $DIR/broken_format.rs:30:20
    |
 LL | fn check_2(_: impl ImportantTrait2) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_2`
 
 warning: positional format arguments are not allowed here
-  --> $DIR/broken_format.rs:11:32
+  --> $DIR/broken_format.rs:12:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^
@@ -107,7 +107,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Test {1}
-  --> $DIR/broken_format.rs:39:13
+  --> $DIR/broken_format.rs:40:13
    |
 LL |     check_3(());
    |     ------- ^^ the trait `ImportantTrait3` is not implemented for `()`
@@ -115,18 +115,18 @@ LL |     check_3(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/broken_format.rs:14:1
+  --> $DIR/broken_format.rs:15:1
    |
 LL | trait ImportantTrait3 {}
    | ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check_3`
-  --> $DIR/broken_format.rs:30:20
+  --> $DIR/broken_format.rs:31:20
    |
 LL | fn check_3(_: impl ImportantTrait3) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_3`
 
 warning: invalid format specifier
-  --> $DIR/broken_format.rs:16:32
+  --> $DIR/broken_format.rs:17:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Test ()
-  --> $DIR/broken_format.rs:41:13
+  --> $DIR/broken_format.rs:42:13
    |
 LL |     check_4(());
    |     ------- ^^ the trait `ImportantTrait4` is not implemented for `()`
@@ -143,18 +143,18 @@ LL |     check_4(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/broken_format.rs:19:1
+  --> $DIR/broken_format.rs:20:1
    |
 LL | trait ImportantTrait4 {}
    | ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check_4`
-  --> $DIR/broken_format.rs:31:20
+  --> $DIR/broken_format.rs:32:20
    |
 LL | fn check_4(_: impl ImportantTrait4) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_4`
 
 warning: expected `}`, found `!`
-  --> $DIR/broken_format.rs:21:32
+  --> $DIR/broken_format.rs:22:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -162,7 +162,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: unmatched `}` found
-  --> $DIR/broken_format.rs:21:32
+  --> $DIR/broken_format.rs:22:32
    |
 LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -170,7 +170,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Test {Self:!}
-  --> $DIR/broken_format.rs:43:13
+  --> $DIR/broken_format.rs:44:13
    |
 LL |     check_5(());
    |     ------- ^^ the trait `ImportantTrait5` is not implemented for `()`
@@ -178,12 +178,12 @@ LL |     check_5(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/broken_format.rs:26:1
+  --> $DIR/broken_format.rs:27:1
    |
 LL | trait ImportantTrait5 {}
    | ^^^^^^^^^^^^^^^^^^^^^
 note: required by a bound in `check_5`
-  --> $DIR/broken_format.rs:32:20
+  --> $DIR/broken_format.rs:33:20
    |
 LL | fn check_5(_: impl ImportantTrait5) {}
    |                    ^^^^^^^^^^^^^^^ required by this bound in `check_5`
diff --git a/tests/ui/traits/custom-on-unimplemented-diagnostic.rs b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs
index d7e257ef3bb..1173c939038 100644
--- a/tests/ui/traits/custom-on-unimplemented-diagnostic.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.on_unimplemented.intro
+//@ reference: attributes.diagnostic.on_unimplemented.keys
 #[diagnostic::on_unimplemented(message = "my message", label = "my label", note = "my note")]
 pub trait ProviderLt {}
 
diff --git a/tests/ui/traits/custom-on-unimplemented-diagnostic.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr
index f9788360d06..4c1838620b3 100644
--- a/tests/ui/traits/custom-on-unimplemented-diagnostic.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/custom-on-unimplemented-diagnostic.stderr
@@ -1,5 +1,5 @@
 error[E0599]: my message
-  --> $DIR/custom-on-unimplemented-diagnostic.rs:15:7
+  --> $DIR/custom-on-unimplemented-diagnostic.rs:17:7
    |
 LL | struct B;
    | -------- method `request` not found for this struct because it doesn't satisfy `B: ProviderExt` or `B: ProviderLt`
@@ -8,7 +8,7 @@ LL |     B.request();
    |       ^^^^^^^ my label
    |
 note: trait bound `B: ProviderLt` was not satisfied
-  --> $DIR/custom-on-unimplemented-diagnostic.rs:10:18
+  --> $DIR/custom-on-unimplemented-diagnostic.rs:12:18
    |
 LL | impl<T: ?Sized + ProviderLt> ProviderExt for T {}
    |                  ^^^^^^^^^^  -----------     -
@@ -16,13 +16,13 @@ LL | impl<T: ?Sized + ProviderLt> ProviderExt for T {}
    |                  unsatisfied trait bound introduced here
    = note: my note
 note: the trait `ProviderLt` must be implemented
-  --> $DIR/custom-on-unimplemented-diagnostic.rs:2:1
+  --> $DIR/custom-on-unimplemented-diagnostic.rs:4:1
    |
 LL | pub trait ProviderLt {}
    | ^^^^^^^^^^^^^^^^^^^^
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `ProviderExt` defines an item `request`, perhaps you need to implement it
-  --> $DIR/custom-on-unimplemented-diagnostic.rs:4:1
+  --> $DIR/custom-on-unimplemented-diagnostic.rs:6:1
    |
 LL | pub trait ProviderExt {
    | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
index 30a85ff2199..b76b550fcb2 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
@@ -1,3 +1,7 @@
+//@ reference: attributes.diagnostic.on_unimplemented.format-parameters
+//@ reference: attributes.diagnostic.on_unimplemented.keys
+//@ reference: attributes.diagnostic.on_unimplemented.syntax
+//@ reference: attributes.diagnostic.on_unimplemented.invalid-formats
 #[diagnostic::on_unimplemented(
     on(_Self = "&str"),
     //~^WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
index e34b917f67e..bb455d92940 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
@@ -1,5 +1,5 @@
 warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:22:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:26:1
    |
 LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:2:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:6:5
    |
 LL |     on(_Self = "&str"),
    |     ^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -15,7 +15,7 @@ LL |     on(_Self = "&str"),
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:8:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:12:5
    |
 LL |     parent_label = "in this scope",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -23,7 +23,7 @@ LL |     parent_label = "in this scope",
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:11:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:15:5
    |
 LL |     append_const_msg
    |     ^^^^^^^^^^^^^^^^ invalid option found here
@@ -31,7 +31,7 @@ LL |     append_const_msg
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:17:32
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:21:32
    |
 LL | #[diagnostic::on_unimplemented = "Message"]
    |                                ^^^^^^^^^^^ invalid option found here
@@ -39,7 +39,7 @@ LL | #[diagnostic::on_unimplemented = "Message"]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: there is no parameter `from_desugaring` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `direct` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `cause` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `integral` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `integer` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `float` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `_Self` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `crate_local` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -103,7 +103,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `Trait` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `ItemContext` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:2:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:6:5
    |
 LL |     on(_Self = "&str"),
    |     ^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -128,7 +128,7 @@ LL |     on(_Self = "&str"),
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:8:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:12:5
    |
 LL |     parent_label = "in this scope",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -137,7 +137,7 @@ LL |     parent_label = "in this scope",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:11:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:15:5
    |
 LL |     append_const_msg
    |     ^^^^^^^^^^^^^^^^ invalid option found here
@@ -146,7 +146,7 @@ LL |     append_const_msg
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: trait has `()` and `i32` as params
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:59:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:63:15
    |
 LL |     takes_foo(());
    |     --------- ^^ trait has `()` and `i32` as params
@@ -156,18 +156,18 @@ LL |     takes_foo(());
    = help: the trait `Foo<i32>` is not implemented for `()`
    = note: trait has `()` and `i32` as params
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:15:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:19:1
    |
 LL | trait Foo<T> {}
    | ^^^^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:54:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:58:22
    |
 LL | fn takes_foo(_: impl Foo<i32>) {}
    |                      ^^^^^^^^ required by this bound in `takes_foo`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:17:32
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:21:32
    |
 LL | #[diagnostic::on_unimplemented = "Message"]
    |                                ^^^^^^^^^^^ invalid option found here
@@ -176,7 +176,7 @@ LL | #[diagnostic::on_unimplemented = "Message"]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `(): Bar` is not satisfied
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:61:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:65:15
    |
 LL |     takes_bar(());
    |     --------- ^^ the trait `Bar` is not implemented for `()`
@@ -185,13 +185,13 @@ LL |     takes_bar(());
    |
    = help: the trait `Bar` is implemented for `i32`
 note: required by a bound in `takes_bar`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:55:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:59:22
    |
 LL | fn takes_bar(_: impl Bar) {}
    |                      ^^^ required by this bound in `takes_bar`
 
 warning: there is no parameter `from_desugaring` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,7 +200,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `direct` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `cause` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -218,7 +218,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `integral` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -227,7 +227,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `integer` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:33:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -236,7 +236,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `float` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -245,7 +245,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `_Self` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -254,7 +254,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `crate_local` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `Trait` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -272,7 +272,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `ItemContext` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -281,7 +281,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: {from_desugaring}{direct}{cause}{integral}{integer}
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:63:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:67:15
    |
 LL |     takes_baz(());
    |     --------- ^^ {float}{_Self}{crate_local}{Trait}{ItemContext}
@@ -290,12 +290,12 @@ LL |     takes_baz(());
    |
    = help: the trait `Baz` is not implemented for `()`
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:52:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:56:1
    |
 LL | trait Baz {}
    | ^^^^^^^^^
 note: required by a bound in `takes_baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:56:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:60:22
    |
 LL | fn takes_baz(_: impl Baz) {}
    |                      ^^^ required by this bound in `takes_baz`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
index b4234066bb1..8328c10d2a0 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.on_unimplemented.syntax
+//@ reference: attributes.diagnostic.on_unimplemented.unknown-keys
 #[diagnostic::on_unimplemented(unsupported = "foo")]
 //~^WARN malformed `on_unimplemented` attribute
 //~|WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
index dc0c1948236..11263580b15 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
@@ -1,5 +1,5 @@
 warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:6:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:8:1
    |
 LL | #[diagnostic::on_unimplemented(message = "Baz")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "Baz")]
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:1:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
    |
 LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    |                                ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -15,7 +15,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:10:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    |                                                  ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -23,7 +23,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
    |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -31,7 +31,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:20:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:22:32
    |
 LL | #[diagnostic::on_unimplemented = "boom"]
    |                                ^^^^^^^^ invalid option found here
@@ -39,7 +39,7 @@ LL | #[diagnostic::on_unimplemented = "boom"]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:24:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL | #[diagnostic::on_unimplemented]
    = help: at least one of the `message`, `note` and `label` options are expected
 
 warning: there is no parameter `DoesNotExist` on trait `Test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:1:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
    |
 LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    |                                ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -64,7 +64,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:41:14
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:14
    |
 LL |     take_foo(1_i32);
    |     -------- ^^^^^ the trait `Foo` is not implemented for `i32`
@@ -72,18 +72,18 @@ LL |     take_foo(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:4:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:6:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `take_foo`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:34:21
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:36:21
    |
 LL | fn take_foo(_: impl Foo) {}
    |                     ^^^ required by this bound in `take_foo`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:10:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    |                                                  ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -92,7 +92,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Boom
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:14
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:45:14
    |
 LL |     take_baz(1_i32);
    |     -------- ^^^^^ the trait `Baz` is not implemented for `i32`
@@ -100,18 +100,18 @@ LL |     take_baz(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:13:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:1
    |
 LL | trait Baz {}
    | ^^^^^^^^^
 note: required by a bound in `take_baz`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:21
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:37:21
    |
 LL | fn take_baz(_: impl Baz) {}
    |                     ^^^ required by this bound in `take_baz`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
    |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -120,7 +120,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Boom
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:45:15
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:15
    |
 LL |     take_boom(1_i32);
    |     --------- ^^^^^ the trait `Boom` is not implemented for `i32`
@@ -128,18 +128,18 @@ LL |     take_boom(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:18:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:20:1
    |
 LL | trait Boom {}
    | ^^^^^^^^^^
 note: required by a bound in `take_boom`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:36:22
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:22
    |
 LL | fn take_boom(_: impl Boom) {}
    |                      ^^^^ required by this bound in `take_boom`
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:24:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -148,7 +148,7 @@ LL | #[diagnostic::on_unimplemented]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `i32: Whatever` is not satisfied
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:19
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:19
    |
 LL |     take_whatever(1_i32);
    |     ------------- ^^^^^ the trait `Whatever` is not implemented for `i32`
@@ -156,18 +156,18 @@ LL |     take_whatever(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:27:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:1
    |
 LL | trait Whatever {}
    | ^^^^^^^^^^^^^^
 note: required by a bound in `take_whatever`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:37:26
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:39:26
    |
 LL | fn take_whatever(_: impl Whatever) {}
    |                          ^^^^^^^^ required by this bound in `take_whatever`
 
 warning: there is no parameter `DoesNotExist` on trait `Test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +176,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: {DoesNotExist}
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:15
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:51:15
    |
 LL |     take_test(());
    |     --------- ^^ the trait `Test` is not implemented for `()`
@@ -184,12 +184,12 @@ LL |     take_test(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:32:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:34:1
    |
 LL | trait Test {}
    | ^^^^^^^^^^
 note: required by a bound in `take_test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:22
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:40:22
    |
 LL | fn take_test(_: impl Test) {}
    |                      ^^^^ required by this bound in `take_test`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.rs b/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.rs
index 7eaff73dca1..dff209d4761 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.rs
@@ -1,4 +1,5 @@
 //@ aux-build:other.rs
+//@ reference: attributes.diagnostic.on_unimplemented.intro
 
 extern crate other;
 
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.stderr
index a9968538d0d..c0dd6d9628a 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/error_is_shown_in_downstream_crates.stderr
@@ -1,5 +1,5 @@
 error[E0277]: Message
-  --> $DIR/error_is_shown_in_downstream_crates.rs:10:14
+  --> $DIR/error_is_shown_in_downstream_crates.rs:11:14
    |
 LL |     take_foo(());
    |     -------- ^^ label
@@ -9,7 +9,7 @@ LL |     take_foo(());
    = help: the trait `Foo` is not implemented for `()`
    = note: Note
 note: required by a bound in `take_foo`
-  --> $DIR/error_is_shown_in_downstream_crates.rs:7:21
+  --> $DIR/error_is_shown_in_downstream_crates.rs:8:21
    |
 LL | fn take_foo(_: impl Foo) {}
    |                     ^^^ required by this bound in `take_foo`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
index 5b25fb234bc..c638681173d 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.on_unimplemented.repetition
+//@ reference: attributes.diagnostic.on_unimplemented.syntax
 #[diagnostic::on_unimplemented(
     if(Self = "()"),
     //~^WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
index 56d125e20e5..e00846da77b 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
@@ -1,5 +1,5 @@
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:2:5
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:4:5
    |
 LL |     if(Self = "()"),
    |     ^^^^^^^^^^^^^^^ invalid option found here
@@ -8,7 +8,7 @@ LL |     if(Self = "()"),
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:8:32
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:10:32
    |
 LL |     message = "custom message",
    |     -------------------------- `message` is first declared here
@@ -17,7 +17,7 @@ LL | #[diagnostic::on_unimplemented(message = "fallback!!")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^ `message` is already declared here
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:2:5
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:4:5
    |
 LL |     if(Self = "()"),
    |     ^^^^^^^^^^^^^^^ invalid option found here
@@ -26,7 +26,7 @@ LL |     if(Self = "()"),
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:8:32
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:10:32
    |
 LL |     message = "custom message",
    |     -------------------------- `message` is first declared here
@@ -37,7 +37,7 @@ LL | #[diagnostic::on_unimplemented(message = "fallback!!")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: custom message
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:18:15
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:20:15
    |
 LL |     takes_foo(());
    |     --------- ^^ fallback label
@@ -48,12 +48,12 @@ LL |     takes_foo(());
    = note: custom note
    = note: fallback note
 help: this trait has no implementations, consider adding one
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:13:1
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:15:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:15:22
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:17:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
index a5982f6492c..dc0f850031e 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
@@ -1,3 +1,4 @@
+//@ reference: attributes.diagnostic.on_unimplemented.note-repetition
 #[diagnostic::on_unimplemented(message = "Foo", label = "Bar", note = "Baz", note = "Boom")]
 trait Foo {}
 
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
index 93a0d0b3f41..6567269be3b 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
@@ -1,5 +1,5 @@
 error[E0277]: Foo
-  --> $DIR/multiple_notes.rs:12:15
+  --> $DIR/multiple_notes.rs:13:15
    |
 LL |     takes_foo(());
    |     --------- ^^ Bar
@@ -10,18 +10,18 @@ LL |     takes_foo(());
    = note: Baz
    = note: Boom
 help: this trait has no implementations, consider adding one
-  --> $DIR/multiple_notes.rs:2:1
+  --> $DIR/multiple_notes.rs:3:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/multiple_notes.rs:8:22
+  --> $DIR/multiple_notes.rs:9:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
 
 error[E0277]: Bar
-  --> $DIR/multiple_notes.rs:14:15
+  --> $DIR/multiple_notes.rs:15:15
    |
 LL |     takes_bar(());
    |     --------- ^^ Foo
@@ -32,12 +32,12 @@ LL |     takes_bar(());
    = note: Baz
    = note: Baz2
 help: this trait has no implementations, consider adding one
-  --> $DIR/multiple_notes.rs:6:1
+  --> $DIR/multiple_notes.rs:7:1
    |
 LL | trait Bar {}
    | ^^^^^^^^^
 note: required by a bound in `takes_bar`
-  --> $DIR/multiple_notes.rs:9:22
+  --> $DIR/multiple_notes.rs:10:22
    |
 LL | fn takes_bar(_: impl Bar) {}
    |                      ^^^ required by this bound in `takes_bar`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
index 7ca03127759..e584077c643 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.on_unimplemented.intro
+//@ reference: attributes.diagnostic.on_unimplemented.keys
 #[diagnostic::on_unimplemented(message = "Foo", label = "Bar", note = "Baz")]
 trait Foo {}
 
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
index 6b17f40c6dd..de57f7044bf 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
@@ -1,5 +1,5 @@
 error[E0277]: Foo
-  --> $DIR/on_unimplemented_simple.rs:7:15
+  --> $DIR/on_unimplemented_simple.rs:9:15
    |
 LL |     takes_foo(());
    |     --------- ^^ Bar
@@ -9,12 +9,12 @@ LL |     takes_foo(());
    = help: the trait `Foo` is not implemented for `()`
    = note: Baz
 help: this trait has no implementations, consider adding one
-  --> $DIR/on_unimplemented_simple.rs:2:1
+  --> $DIR/on_unimplemented_simple.rs:4:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/on_unimplemented_simple.rs:4:22
+  --> $DIR/on_unimplemented_simple.rs:6:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
index 8c0b8150417..d0eb608c40f 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
@@ -1,3 +1,4 @@
+//@ reference: attributes.diagnostic.on_unimplemented.repetition
 #[diagnostic::on_unimplemented(
     message = "first message",
     label = "first label",
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
index 43ab6bf25a1..feafe2cee76 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
@@ -1,5 +1,5 @@
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/report_warning_on_duplicated_options.rs:7:5
+  --> $DIR/report_warning_on_duplicated_options.rs:8:5
    |
 LL |     message = "first message",
    |     ------------------------- `message` is first declared here
@@ -10,7 +10,7 @@ LL |     message = "second message",
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: `label` is ignored due to previous definition of `label`
-  --> $DIR/report_warning_on_duplicated_options.rs:10:5
+  --> $DIR/report_warning_on_duplicated_options.rs:11:5
    |
 LL |     label = "first label",
    |     --------------------- `label` is first declared here
@@ -19,7 +19,7 @@ LL |     label = "second label",
    |     ^^^^^^^^^^^^^^^^^^^^^^ `label` is already declared here
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/report_warning_on_duplicated_options.rs:7:5
+  --> $DIR/report_warning_on_duplicated_options.rs:8:5
    |
 LL |     message = "first message",
    |     ------------------------- `message` is first declared here
@@ -30,7 +30,7 @@ LL |     message = "second message",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: `label` is ignored due to previous definition of `label`
-  --> $DIR/report_warning_on_duplicated_options.rs:10:5
+  --> $DIR/report_warning_on_duplicated_options.rs:11:5
    |
 LL |     label = "first label",
    |     --------------------- `label` is first declared here
@@ -41,7 +41,7 @@ LL |     label = "second label",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: first message
-  --> $DIR/report_warning_on_duplicated_options.rs:21:15
+  --> $DIR/report_warning_on_duplicated_options.rs:22:15
    |
 LL |     takes_foo(());
    |     --------- ^^ first label
@@ -52,12 +52,12 @@ LL |     takes_foo(());
    = note: custom note
    = note: second note
 help: this trait has no implementations, consider adding one
-  --> $DIR/report_warning_on_duplicated_options.rs:15:1
+  --> $DIR/report_warning_on_duplicated_options.rs:16:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/report_warning_on_duplicated_options.rs:18:22
+  --> $DIR/report_warning_on_duplicated_options.rs:19:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.rs b/tests/ui/diagnostic_namespace/suggest_typos.rs
index b25f097a8ad..6fa4f800462 100644
--- a/tests/ui/diagnostic_namespace/suggest_typos.rs
+++ b/tests/ui/diagnostic_namespace/suggest_typos.rs
@@ -1,3 +1,4 @@
+//@ reference: attributes.diagnostic.namespace.unknown-invalid-syntax
 #![deny(unknown_or_malformed_diagnostic_attributes)]
 
 #[diagnostic::onunimplemented]
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr
index 307311258f2..ff4ee9717d4 100644
--- a/tests/ui/diagnostic_namespace/suggest_typos.stderr
+++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr
@@ -1,11 +1,11 @@
 error: unknown diagnostic attribute
-  --> $DIR/suggest_typos.rs:3:15
+  --> $DIR/suggest_typos.rs:4:15
    |
 LL | #[diagnostic::onunimplemented]
    |               ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/suggest_typos.rs:1:9
+  --> $DIR/suggest_typos.rs:2:9
    |
 LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | #[diagnostic::on_unimplemented]
    |               ~~~~~~~~~~~~~~~~
 
 error: unknown diagnostic attribute
-  --> $DIR/suggest_typos.rs:8:15
+  --> $DIR/suggest_typos.rs:9:15
    |
 LL | #[diagnostic::un_onimplemented]
    |               ^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | #[diagnostic::on_unimplemented]
    |               ~~~~~~~~~~~~~~~~
 
 error: unknown diagnostic attribute
-  --> $DIR/suggest_typos.rs:13:15
+  --> $DIR/suggest_typos.rs:14:15
    |
 LL | #[diagnostic::on_implemented]
    |               ^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/negative-bounds/on-unimplemented.rs b/tests/ui/traits/negative-bounds/on-unimplemented.rs
index 34582590861..5f2a705ed56 100644
--- a/tests/ui/traits/negative-bounds/on-unimplemented.rs
+++ b/tests/ui/traits/negative-bounds/on-unimplemented.rs
@@ -1,3 +1,5 @@
+//@ reference: attributes.diagnostic.on_unimplemented.intro
+
 #![feature(negative_bounds)]
 
 #[diagnostic::on_unimplemented(message = "this ain't fooing")]
diff --git a/tests/ui/traits/negative-bounds/on-unimplemented.stderr b/tests/ui/traits/negative-bounds/on-unimplemented.stderr
index ed473d57917..8a295611010 100644
--- a/tests/ui/traits/negative-bounds/on-unimplemented.stderr
+++ b/tests/ui/traits/negative-bounds/on-unimplemented.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `NotFoo: !Foo` is not satisfied
-  --> $DIR/on-unimplemented.rs:7:15
+  --> $DIR/on-unimplemented.rs:9:15
    |
 LL | fn hello() -> impl !Foo {
    |               ^^^^^^^^^ the trait bound `NotFoo: !Foo` is not satisfied