about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-01-12 23:08:30 +0000
committerbors <bors@rust-lang.org>2025-01-12 23:08:30 +0000
commite7ad3ae331bf2716389c10e01612e201a7f98c8d (patch)
treefba1893a621dc7f495dd66d6bde0557061bf3d06
parent48a426eca9df23b24b3559e545cf88dee61d4de9 (diff)
parent223a7c12373034817eab620005397edd65b66ef8 (diff)
downloadrust-e7ad3ae331bf2716389c10e01612e201a7f98c8d.tar.gz
rust-e7ad3ae331bf2716389c10e01612e201a7f98c8d.zip
Auto merge of #135420 - GuillaumeGomez:rollup-93vepka, r=GuillaumeGomez
Rollup of 7 pull requests

Successful merges:

 - #135348 (rustdoc-json: Include items in stripped modules in `Crate::paths`.)
 - #135365 (Update the explanation for why we use box_new in vec!)
 - #135383 (De-abstract tagged ptr and make it covariant)
 - #135401 (Remove some empty expected files to fix blessing)
 - #135406 (Update unstable lint docs to include required feature attributes)
 - #135407 (Deny various clippy lints)
 - #135411 (run_make_support: add `#![warn(unreachable_pub)]`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_data_structures/src/marker.rs4
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr.rs357
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy.rs330
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs50
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/drop.rs178
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs72
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs144
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs34
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/tests.rs105
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs15
-rw-r--r--compiler/rustc_lint/src/unqualified_local_imports.rs1
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs4
-rw-r--r--compiler/rustc_middle/src/ty/list.rs2
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs2
-rw-r--r--library/alloc/src/macros.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs28
-rw-r--r--src/librustdoc/formats/cache.rs23
-rw-r--r--src/tools/jsondocck/src/main.rs27
-rw-r--r--src/tools/jsondoclint/src/validator.rs6
-rw-r--r--src/tools/jsondoclint/src/validator/tests.rs97
-rw-r--r--src/tools/run-make-support/src/lib.rs1
-rw-r--r--tests/rustdoc-json/reexport/simple_private.rs6
-rw-r--r--tests/rustdoc-json/reexport/simple_public.rs5
-rw-r--r--tests/rustdoc-ui/crate-reference-in-block-module.stderr0
-rw-r--r--tests/rustdoc-ui/macro-docs.stdout0
25 files changed, 483 insertions, 1012 deletions
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
index 2b629024bfe..6ae97222f77 100644
--- a/compiler/rustc_data_structures/src/marker.rs
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -72,7 +72,7 @@ impl_dyn_send!(
     [Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend]
     [Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend]
     [crate::sync::RwLock<T> where T: DynSend]
-    [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool]
+    [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Send + crate::tagged_ptr::Tag]
     [rustc_arena::TypedArena<T> where T: DynSend]
     [indexmap::IndexSet<V, S> where V: DynSend, S: DynSend]
     [indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
@@ -148,7 +148,7 @@ impl_dyn_sync!(
     [crate::sync::RwLock<T> where T: DynSend + DynSync]
     [crate::sync::WorkerLocal<T> where T: DynSend]
     [crate::intern::Interned<'a, T> where 'a, T: DynSync]
-    [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
+    [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Sync + crate::tagged_ptr::Tag]
     [parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend]
     [parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync]
     [indexmap::IndexSet<V, S> where V: DynSync, S: DynSync]
diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs
index 2914eece679..94db421f77e 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr.rs
@@ -1,116 +1,26 @@
-//! This module implements tagged pointers.
+//! This module implements tagged pointers. In order to utilize the pointer
+//! packing, you must have a tag type implementing the [`Tag`] trait.
 //!
-//! In order to utilize the pointer packing, you must have two types: a pointer,
-//! and a tag.
-//!
-//! The pointer must implement the [`Pointer`] trait, with the primary
-//! requirement being convertible to and from a raw pointer. Note that the
-//! pointer must be dereferenceable, so raw pointers generally cannot implement
-//! the [`Pointer`] trait. This implies that the pointer must also be non-null.
-//!
-//! Many common pointer types already implement the [`Pointer`] trait.
-//!
-//! The tag must implement the [`Tag`] trait.
-//!
-//! We assert that the tag and the [`Pointer`] types are compatible at compile
+//! We assert that the tag and the reference type is compatible at compile
 //! time.
 
+use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
+use std::num::NonZero;
 use std::ops::Deref;
 use std::ptr::NonNull;
-use std::rc::Rc;
-use std::sync::Arc;
 
 use crate::aligned::Aligned;
+use crate::stable_hasher::{HashStable, StableHasher};
 
-mod copy;
-mod drop;
-mod impl_tag;
-
-pub use copy::CopyTaggedPtr;
-pub use drop::TaggedPtr;
-
-/// This describes the pointer type encapsulated by [`TaggedPtr`] and
-/// [`CopyTaggedPtr`].
-///
-/// # Safety
-///
-/// The pointer returned from [`into_ptr`] must be a [valid], pointer to
-/// [`<Self as Deref>::Target`].
-///
-/// Note that if `Self` implements [`DerefMut`] the pointer returned from
-/// [`into_ptr`] must be valid for writes (and thus calling [`NonNull::as_mut`]
-/// on it must be safe).
-///
-/// The [`BITS`] constant must be correct. [`BITS`] least-significant bits,
-/// must be zero on all pointers returned from [`into_ptr`].
-///
-/// For example, if the alignment of [`Self::Target`] is 2, then `BITS` should be 1.
-///
-/// [`BITS`]: Pointer::BITS
-/// [`into_ptr`]: Pointer::into_ptr
-/// [valid]: std::ptr#safety
-/// [`<Self as Deref>::Target`]: Deref::Target
-/// [`Self::Target`]: Deref::Target
-/// [`DerefMut`]: std::ops::DerefMut
-pub unsafe trait Pointer: Deref {
-    /// Number of unused (always zero) **least-significant bits** in this
-    /// pointer, usually related to the pointees alignment.
-    ///
-    /// For example if [`BITS`] = `2`, then given `ptr = Self::into_ptr(..)`,
-    /// `ptr.addr() & 0b11 == 0` must be true.
-    ///
-    /// Most likely the value you want to use here is the following, unless
-    /// your [`Self::Target`] type is unsized (e.g., `ty::List<T>` in rustc)
-    /// or your pointer is over/under aligned, in which case you'll need to
-    /// manually figure out what the right type to pass to [`bits_for`] is, or
-    /// what the value to set here.
-    ///
-    /// ```rust
-    /// # use std::ops::Deref;
-    /// # use rustc_data_structures::tagged_ptr::bits_for;
-    /// # struct T;
-    /// # impl Deref for T { type Target = u8; fn deref(&self) -> &u8 { &0 } }
-    /// # impl T {
-    /// const BITS: u32 = bits_for::<<Self as Deref>::Target>();
-    /// # }
-    /// ```
-    ///
-    /// [`BITS`]: Pointer::BITS
-    /// [`Self::Target`]: Deref::Target
-    const BITS: u32;
-
-    /// Turns this pointer into a raw, non-null pointer.
-    ///
-    /// The inverse of this function is [`from_ptr`].
-    ///
-    /// This function guarantees that the least-significant [`Self::BITS`] bits
-    /// are zero.
-    ///
-    /// [`from_ptr`]: Pointer::from_ptr
-    /// [`Self::BITS`]: Pointer::BITS
-    fn into_ptr(self) -> NonNull<Self::Target>;
-
-    /// Re-creates the original pointer, from a raw pointer returned by [`into_ptr`].
-    ///
-    /// # Safety
-    ///
-    /// The passed `ptr` must be returned from [`into_ptr`].
-    ///
-    /// This acts as [`ptr::read::<Self>()`] semantically, it should not be called more than
-    /// once on non-[`Copy`] `Pointer`s.
-    ///
-    /// [`into_ptr`]: Pointer::into_ptr
-    /// [`ptr::read::<Self>()`]: std::ptr::read
-    unsafe fn from_ptr(ptr: NonNull<Self::Target>) -> Self;
-}
-
-/// This describes tags that the [`TaggedPtr`] struct can hold.
+/// This describes tags that the [`TaggedRef`] struct can hold.
 ///
 /// # Safety
 ///
-/// The [`BITS`] constant must be correct.
-///
-/// No more than [`BITS`] least-significant bits may be set in the returned usize.
+/// - The [`BITS`] constant must be correct.
+/// - No more than [`BITS`] least-significant bits may be set in the returned usize.
+/// - [`Eq`] and [`Hash`] must be implementable with the returned `usize` from `into_usize`.
 ///
 /// [`BITS`]: Tag::BITS
 pub unsafe trait Tag: Copy {
@@ -166,118 +76,217 @@ pub const fn bits_for_tags(mut tags: &[usize]) -> u32 {
     bits
 }
 
-unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
-    const BITS: u32 = bits_for::<Self::Target>();
+/// A covariant [`Copy`] tagged borrow. This is essentially `{ pointer: &'a P, tag: T }` packed
+/// in a single reference.
+pub struct TaggedRef<'a, Pointee: Aligned + ?Sized, T: Tag> {
+    /// This is semantically a pair of `pointer: &'a P` and `tag: T` fields,
+    /// however we pack them in a single pointer, to save space.
+    ///
+    /// We pack the tag into the **most**-significant bits of the pointer to
+    /// ease retrieval of the value. A left shift is a multiplication and
+    /// those are embeddable in instruction encoding, for example:
+    ///
+    /// ```asm
+    /// // (<https://godbolt.org/z/jqcYPWEr3>)
+    /// example::shift_read3:
+    ///     mov     eax, dword ptr [8*rdi]
+    ///     ret
+    ///
+    /// example::mask_read3:
+    ///     and     rdi, -8
+    ///     mov     eax, dword ptr [rdi]
+    ///     ret
+    /// ```
+    ///
+    /// This is ASM outputted by rustc for reads of values behind tagged
+    /// pointers for different approaches of tagging:
+    /// - `shift_read3` uses `<< 3` (the tag is in the most-significant bits)
+    /// - `mask_read3` uses `& !0b111` (the tag is in the least-significant bits)
+    ///
+    /// The shift approach thus produces less instructions and is likely faster
+    /// (see <https://godbolt.org/z/Y913sMdWb>).
+    ///
+    /// Encoding diagram:
+    /// ```text
+    /// [ packed.addr                     ]
+    /// [ tag ] [ pointer.addr >> T::BITS ] <-- usize::BITS - T::BITS bits
+    ///    ^
+    ///    |
+    /// T::BITS bits
+    /// ```
+    ///
+    /// The tag can be retrieved by `packed.addr() >> T::BITS` and the pointer
+    /// can be retrieved by `packed.map_addr(|addr| addr << T::BITS)`.
+    packed: NonNull<Pointee>,
+    tag_pointer_ghost: PhantomData<(&'a Pointee, T)>,
+}
 
+impl<'a, P, T> TaggedRef<'a, P, T>
+where
+    P: Aligned + ?Sized,
+    T: Tag,
+{
+    /// Tags `pointer` with `tag`.
+    ///
+    /// [`TaggedRef`]: crate::tagged_ptr::TaggedRef
     #[inline]
-    fn into_ptr(self) -> NonNull<T> {
-        // Safety: pointers from `Box::into_raw` are valid & non-null
-        unsafe { NonNull::new_unchecked(Box::into_raw(self)) }
+    pub fn new(pointer: &'a P, tag: T) -> Self {
+        Self { packed: Self::pack(NonNull::from(pointer), tag), tag_pointer_ghost: PhantomData }
     }
 
+    /// Retrieves the pointer.
     #[inline]
-    unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
-        // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw`
-        unsafe { Box::from_raw(ptr.as_ptr()) }
+    pub fn pointer(self) -> &'a P {
+        // SAFETY: pointer_raw returns the original pointer
+        unsafe { self.pointer_raw().as_ref() }
     }
-}
-
-unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
-    const BITS: u32 = bits_for::<Self::Target>();
 
+    /// Retrieves the tag.
     #[inline]
-    fn into_ptr(self) -> NonNull<T> {
-        // Safety: pointers from `Rc::into_raw` are valid & non-null
-        unsafe { NonNull::new_unchecked(Rc::into_raw(self).cast_mut()) }
+    pub fn tag(&self) -> T {
+        // Unpack the tag, according to the `self.packed` encoding scheme
+        let tag = self.packed.addr().get() >> Self::TAG_BIT_SHIFT;
+
+        // Safety:
+        // The shift retrieves the original value from `T::into_usize`,
+        // satisfying `T::from_usize`'s preconditions.
+        unsafe { T::from_usize(tag) }
     }
 
+    /// Sets the tag to a new value.
     #[inline]
-    unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
-        // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw`
-        unsafe { Rc::from_raw(ptr.as_ptr()) }
+    pub fn set_tag(&mut self, tag: T) {
+        self.packed = Self::pack(self.pointer_raw(), tag);
     }
-}
 
-unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
-    const BITS: u32 = bits_for::<Self::Target>();
+    const TAG_BIT_SHIFT: u32 = usize::BITS - T::BITS;
+    const ASSERTION: () = { assert!(T::BITS <= bits_for::<P>()) };
 
+    /// Pack pointer `ptr` with a `tag`, according to `self.packed` encoding scheme.
     #[inline]
-    fn into_ptr(self) -> NonNull<T> {
-        // Safety: pointers from `Arc::into_raw` are valid & non-null
-        unsafe { NonNull::new_unchecked(Arc::into_raw(self).cast_mut()) }
+    fn pack(ptr: NonNull<P>, tag: T) -> NonNull<P> {
+        // Trigger assert!
+        let () = Self::ASSERTION;
+
+        let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT;
+
+        ptr.map_addr(|addr| {
+            // Safety:
+            // - The pointer is `NonNull` => it's address is `NonZero<usize>`
+            // - `P::BITS` least significant bits are always zero (`Pointer` contract)
+            // - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
+            //
+            // Thus `addr >> T::BITS` is guaranteed to be non-zero.
+            //
+            // `{non_zero} | packed_tag` can't make the value zero.
+
+            let packed = (addr.get() >> T::BITS) | packed_tag;
+            unsafe { NonZero::new_unchecked(packed) }
+        })
     }
 
+    /// Retrieves the original raw pointer from `self.packed`.
     #[inline]
-    unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
-        // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw`
-        unsafe { Arc::from_raw(ptr.as_ptr()) }
+    pub(super) fn pointer_raw(&self) -> NonNull<P> {
+        self.packed.map_addr(|addr| unsafe { NonZero::new_unchecked(addr.get() << T::BITS) })
     }
 }
 
-unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
-    const BITS: u32 = bits_for::<Self::Target>();
+impl<P, T> Copy for TaggedRef<'_, P, T>
+where
+    P: Aligned + ?Sized,
+    T: Tag,
+{
+}
 
+impl<P, T> Clone for TaggedRef<'_, P, T>
+where
+    P: Aligned + ?Sized,
+    T: Tag,
+{
     #[inline]
-    fn into_ptr(self) -> NonNull<T> {
-        NonNull::from(self)
+    fn clone(&self) -> Self {
+        *self
     }
+}
+
+impl<P, T> Deref for TaggedRef<'_, P, T>
+where
+    P: Aligned + ?Sized,
+    T: Tag,
+{
+    type Target = P;
 
     #[inline]
-    unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
-        // Safety:
-        // `ptr` comes from `into_ptr` which gets the pointer from a reference
-        unsafe { ptr.as_ref() }
+    fn deref(&self) -> &Self::Target {
+        self.pointer()
     }
 }
 
-unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
-    const BITS: u32 = bits_for::<Self::Target>();
+impl<P, T> fmt::Debug for TaggedRef<'_, P, T>
+where
+    P: Aligned + fmt::Debug + ?Sized,
+    T: Tag + fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("TaggedRef")
+            .field("pointer", &self.pointer())
+            .field("tag", &self.tag())
+            .finish()
+    }
+}
 
+impl<P, T> PartialEq for TaggedRef<'_, P, T>
+where
+    P: Aligned + ?Sized,
+    T: Tag,
+{
     #[inline]
-    fn into_ptr(self) -> NonNull<T> {
-        NonNull::from(self)
+    #[allow(ambiguous_wide_pointer_comparisons)]
+    fn eq(&self, other: &Self) -> bool {
+        self.packed == other.packed
     }
+}
 
+impl<P, T: Tag> Eq for TaggedRef<'_, P, T> {}
+
+impl<P, T: Tag> Hash for TaggedRef<'_, P, T> {
     #[inline]
-    unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self {
-        // Safety:
-        // `ptr` comes from `into_ptr` which gets the pointer from a reference
-        unsafe { ptr.as_mut() }
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.packed.hash(state);
     }
 }
 
-/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-#[cfg(test)]
-enum Tag2 {
-    B00 = 0b00,
-    B01 = 0b01,
-    B10 = 0b10,
-    B11 = 0b11,
+impl<'a, P, T, HCX> HashStable<HCX> for TaggedRef<'a, P, T>
+where
+    P: HashStable<HCX> + Aligned + ?Sized,
+    T: Tag + HashStable<HCX>,
+{
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
+        self.pointer().hash_stable(hcx, hasher);
+        self.tag().hash_stable(hcx, hasher);
+    }
 }
 
-#[cfg(test)]
-unsafe impl Tag for Tag2 {
-    const BITS: u32 = 2;
-
-    fn into_usize(self) -> usize {
-        self as _
-    }
+// Safety:
+// `TaggedRef<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
+// it's ok to implement `Sync` as long as `P: Sync, T: Sync`
+unsafe impl<P, T> Sync for TaggedRef<'_, P, T>
+where
+    P: Sync + Aligned + ?Sized,
+    T: Sync + Tag,
+{
+}
 
-    unsafe fn from_usize(tag: usize) -> Self {
-        match tag {
-            0b00 => Tag2::B00,
-            0b01 => Tag2::B01,
-            0b10 => Tag2::B10,
-            0b11 => Tag2::B11,
-            _ => unreachable!(),
-        }
-    }
+// Safety:
+// `TaggedRef<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
+// it's ok to implement `Send` as long as `P: Send, T: Send`
+unsafe impl<P, T> Send for TaggedRef<'_, P, T>
+where
+    P: Sync + Aligned + ?Sized,
+    T: Send + Tag,
+{
 }
 
 #[cfg(test)]
-impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 {
-    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) {
-        (*self as u8).hash_stable(hcx, hasher);
-    }
-}
+mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
deleted file mode 100644
index 25e107b0f41..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
+++ /dev/null
@@ -1,330 +0,0 @@
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::marker::PhantomData;
-use std::mem::ManuallyDrop;
-use std::num::NonZero;
-use std::ops::{Deref, DerefMut};
-use std::ptr::NonNull;
-
-use super::{Pointer, Tag};
-use crate::stable_hasher::{HashStable, StableHasher};
-
-/// A [`Copy`] tagged pointer.
-///
-/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer.
-///
-/// You should use this instead of the [`TaggedPtr`] type in all cases where
-/// `P` implements [`Copy`].
-///
-/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
-/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`];
-/// if you want that, wrap the [`CopyTaggedPtr`].
-///
-/// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
-pub struct CopyTaggedPtr<P, T, const COMPARE_PACKED: bool>
-where
-    P: Pointer,
-    T: Tag,
-{
-    /// This is semantically a pair of `pointer: P` and `tag: T` fields,
-    /// however we pack them in a single pointer, to save space.
-    ///
-    /// We pack the tag into the **most**-significant bits of the pointer to
-    /// ease retrieval of the value. A left shift is a multiplication and
-    /// those are embeddable in instruction encoding, for example:
-    ///
-    /// ```asm
-    /// // (<https://godbolt.org/z/jqcYPWEr3>)
-    /// example::shift_read3:
-    ///     mov     eax, dword ptr [8*rdi]
-    ///     ret
-    ///
-    /// example::mask_read3:
-    ///     and     rdi, -8
-    ///     mov     eax, dword ptr [rdi]
-    ///     ret
-    /// ```
-    ///
-    /// This is ASM outputted by rustc for reads of values behind tagged
-    /// pointers for different approaches of tagging:
-    /// - `shift_read3` uses `<< 3` (the tag is in the most-significant bits)
-    /// - `mask_read3` uses `& !0b111` (the tag is in the least-significant bits)
-    ///
-    /// The shift approach thus produces less instructions and is likely faster
-    /// (see <https://godbolt.org/z/Y913sMdWb>).
-    ///
-    /// Encoding diagram:
-    /// ```text
-    /// [ packed.addr                     ]
-    /// [ tag ] [ pointer.addr >> T::BITS ] <-- usize::BITS - T::BITS bits
-    ///    ^
-    ///    |
-    /// T::BITS bits
-    /// ```
-    ///
-    /// The tag can be retrieved by `packed.addr() >> T::BITS` and the pointer
-    /// can be retrieved by `packed.map_addr(|addr| addr << T::BITS)`.
-    packed: NonNull<P::Target>,
-    tag_ghost: PhantomData<T>,
-}
-
-// Note that even though `CopyTaggedPtr` is only really expected to work with
-// `P: Copy`, can't add `P: Copy` bound, because `CopyTaggedPtr` is used in the
-// `TaggedPtr`'s implementation.
-impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer,
-    T: Tag,
-{
-    /// Tags `pointer` with `tag`.
-    ///
-    /// Note that this leaks `pointer`: it won't be dropped when
-    /// `CopyTaggedPtr` is dropped. If you have a pointer with a significant
-    /// drop, use [`TaggedPtr`] instead.
-    ///
-    /// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr
-    #[inline]
-    pub fn new(pointer: P, tag: T) -> Self {
-        Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_ghost: PhantomData }
-    }
-
-    /// Retrieves the pointer.
-    #[inline]
-    pub fn pointer(self) -> P
-    where
-        P: Copy,
-    {
-        // SAFETY: pointer_raw returns the original pointer
-        //
-        // Note that this isn't going to double-drop or anything because we have
-        // P: Copy
-        unsafe { P::from_ptr(self.pointer_raw()) }
-    }
-
-    /// Retrieves the tag.
-    #[inline]
-    pub fn tag(&self) -> T {
-        // Unpack the tag, according to the `self.packed` encoding scheme
-        let tag = self.packed.addr().get() >> Self::TAG_BIT_SHIFT;
-
-        // Safety:
-        // The shift retrieves the original value from `T::into_usize`,
-        // satisfying `T::from_usize`'s preconditions.
-        unsafe { T::from_usize(tag) }
-    }
-
-    /// Sets the tag to a new value.
-    #[inline]
-    pub fn set_tag(&mut self, tag: T) {
-        self.packed = Self::pack(self.pointer_raw(), tag);
-    }
-
-    const TAG_BIT_SHIFT: u32 = usize::BITS - T::BITS;
-    const ASSERTION: () = { assert!(T::BITS <= P::BITS) };
-
-    /// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`,
-    /// according to `self.packed` encoding scheme.
-    ///
-    /// [`P::into_ptr`]: Pointer::into_ptr
-    #[inline]
-    fn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target> {
-        // Trigger assert!
-        let () = Self::ASSERTION;
-
-        let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT;
-
-        ptr.map_addr(|addr| {
-            // Safety:
-            // - The pointer is `NonNull` => it's address is `NonZero<usize>`
-            // - `P::BITS` least significant bits are always zero (`Pointer` contract)
-            // - `T::BITS <= P::BITS` (from `Self::ASSERTION`)
-            //
-            // Thus `addr >> T::BITS` is guaranteed to be non-zero.
-            //
-            // `{non_zero} | packed_tag` can't make the value zero.
-
-            let packed = (addr.get() >> T::BITS) | packed_tag;
-            unsafe { NonZero::new_unchecked(packed) }
-        })
-    }
-
-    /// Retrieves the original raw pointer from `self.packed`.
-    #[inline]
-    pub(super) fn pointer_raw(&self) -> NonNull<P::Target> {
-        self.packed.map_addr(|addr| unsafe { NonZero::new_unchecked(addr.get() << T::BITS) })
-    }
-
-    /// This provides a reference to the `P` pointer itself, rather than the
-    /// `Deref::Target`. It is used for cases where we want to call methods
-    /// that may be implement differently for the Pointer than the Pointee
-    /// (e.g., `Rc::clone` vs cloning the inner value).
-    pub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R {
-        // Safety:
-        // - `self.raw.pointer_raw()` is originally returned from `P::into_ptr`
-        //   and as such is valid for `P::from_ptr`.
-        //   - This also allows us to not care whatever `f` panics or not.
-        // - Even though we create a copy of the pointer, we store it inside
-        //   `ManuallyDrop` and only access it by-ref, so we don't double-drop.
-        //
-        // Semantically this is just `f(&self.pointer)` (where `self.pointer`
-        // is non-packed original pointer).
-        //
-        // Note that even though `CopyTaggedPtr` is only really expected to
-        // work with `P: Copy`, we have to assume `P: ?Copy`, because
-        // `CopyTaggedPtr` is used in the `TaggedPtr`'s implementation.
-        let ptr = unsafe { ManuallyDrop::new(P::from_ptr(self.pointer_raw())) };
-        f(&ptr)
-    }
-}
-
-impl<P, T, const CP: bool> Copy for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer + Copy,
-    T: Tag,
-{
-}
-
-impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer + Copy,
-    T: Tag,
-{
-    #[inline]
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer,
-    T: Tag,
-{
-    type Target = P::Target;
-
-    #[inline]
-    fn deref(&self) -> &Self::Target {
-        // Safety:
-        // `pointer_raw` returns the original pointer from `P::into_ptr` which,
-        // by the `Pointer`'s contract, must be valid.
-        unsafe { self.pointer_raw().as_ref() }
-    }
-}
-
-impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer + DerefMut,
-    T: Tag,
-{
-    #[inline]
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        // Safety:
-        // `pointer_raw` returns the original pointer from `P::into_ptr` which,
-        // by the `Pointer`'s contract, must be valid for writes if
-        // `P: DerefMut`.
-        unsafe { self.pointer_raw().as_mut() }
-    }
-}
-
-impl<P, T, const CP: bool> fmt::Debug for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer + fmt::Debug,
-    T: Tag + fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.with_pointer_ref(|ptr| {
-            f.debug_struct("CopyTaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish()
-        })
-    }
-}
-
-impl<P, T> PartialEq for CopyTaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-    #[inline]
-    #[allow(ambiguous_wide_pointer_comparisons)]
-    fn eq(&self, other: &Self) -> bool {
-        self.packed == other.packed
-    }
-}
-
-impl<P, T> Eq for CopyTaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-}
-
-impl<P, T> Hash for CopyTaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-    #[inline]
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.packed.hash(state);
-    }
-}
-
-impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP>
-where
-    P: Pointer + HashStable<HCX>,
-    T: Tag + HashStable<HCX>,
-{
-    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
-        self.with_pointer_ref(|ptr| ptr.hash_stable(hcx, hasher));
-        self.tag().hash_stable(hcx, hasher);
-    }
-}
-
-// Safety:
-// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
-// it's ok to implement `Sync` as long as `P: Sync, T: Sync`
-unsafe impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP>
-where
-    P: Sync + Pointer,
-    T: Sync + Tag,
-{
-}
-
-// Safety:
-// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such
-// it's ok to implement `Send` as long as `P: Send, T: Send`
-unsafe impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP>
-where
-    P: Send + Pointer,
-    T: Send + Tag,
-{
-}
-
-/// Test that `new` does not compile if there is not enough alignment for the
-/// tag in the pointer.
-///
-/// ```compile_fail,E0080
-/// use rustc_data_structures::tagged_ptr::{CopyTaggedPtr, Tag};
-///
-/// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
-///
-/// unsafe impl Tag for Tag2 {
-///     const BITS: u32 = 2;
-///
-///     fn into_usize(self) -> usize { todo!() }
-///     unsafe fn from_usize(tag: usize) -> Self { todo!() }
-/// }
-///
-/// let value = 12u16;
-/// let reference = &value;
-/// let tag = Tag2::B01;
-///
-/// let _ptr = CopyTaggedPtr::<_, _, true>::new(reference, tag);
-/// ```
-// For some reason miri does not get the compile error
-// probably it `check`s instead of `build`ing?
-#[cfg(not(miri))]
-const _: () = ();
-
-#[cfg(test)]
-mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs
deleted file mode 100644
index 160af8a65d9..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use std::ptr;
-
-use crate::hashes::Hash128;
-use crate::stable_hasher::{HashStable, StableHasher};
-use crate::tagged_ptr::{CopyTaggedPtr, Pointer, Tag, Tag2};
-
-#[test]
-fn smoke() {
-    let value = 12u32;
-    let reference = &value;
-    let tag = Tag2::B01;
-
-    let ptr = tag_ptr(reference, tag);
-
-    assert_eq!(ptr.tag(), tag);
-    assert_eq!(*ptr, 12);
-    assert!(ptr::eq(ptr.pointer(), reference));
-
-    let copy = ptr;
-
-    let mut ptr = ptr;
-    ptr.set_tag(Tag2::B00);
-    assert_eq!(ptr.tag(), Tag2::B00);
-
-    assert_eq!(copy.tag(), tag);
-    assert_eq!(*copy, 12);
-    assert!(ptr::eq(copy.pointer(), reference));
-}
-
-#[test]
-fn stable_hash_hashes_as_tuple() {
-    let hash_packed = {
-        let mut hasher = StableHasher::new();
-        tag_ptr(&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
-        hasher.finish::<Hash128>()
-    };
-
-    let hash_tupled = {
-        let mut hasher = StableHasher::new();
-        (&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
-        hasher.finish::<Hash128>()
-    };
-
-    assert_eq!(hash_packed, hash_tupled);
-}
-
-/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter.
-fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> CopyTaggedPtr<P, T, true> {
-    CopyTaggedPtr::new(ptr, tag)
-}
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
deleted file mode 100644
index 319a8cdd399..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs
+++ /dev/null
@@ -1,178 +0,0 @@
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::{Deref, DerefMut};
-
-use super::{CopyTaggedPtr, Pointer, Tag};
-use crate::stable_hasher::{HashStable, StableHasher};
-
-/// A tagged pointer that supports pointers that implement [`Drop`].
-///
-/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer.
-///
-/// You should use [`CopyTaggedPtr`] instead of the this type in all cases
-/// where `P` implements [`Copy`].
-///
-/// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
-/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`];
-/// if you want that, wrap the [`TaggedPtr`].
-pub struct TaggedPtr<P, T, const COMPARE_PACKED: bool>
-where
-    P: Pointer,
-    T: Tag,
-{
-    raw: CopyTaggedPtr<P, T, COMPARE_PACKED>,
-}
-
-impl<P, T, const CP: bool> TaggedPtr<P, T, CP>
-where
-    P: Pointer,
-    T: Tag,
-{
-    /// Tags `pointer` with `tag`.
-    #[inline]
-    pub fn new(pointer: P, tag: T) -> Self {
-        TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) }
-    }
-
-    /// Retrieves the tag.
-    #[inline]
-    pub fn tag(&self) -> T {
-        self.raw.tag()
-    }
-
-    /// Sets the tag to a new value.
-    #[inline]
-    pub fn set_tag(&mut self, tag: T) {
-        self.raw.set_tag(tag)
-    }
-}
-
-impl<P, T, const CP: bool> Clone for TaggedPtr<P, T, CP>
-where
-    P: Pointer + Clone,
-    T: Tag,
-{
-    fn clone(&self) -> Self {
-        let ptr = self.raw.with_pointer_ref(P::clone);
-
-        Self::new(ptr, self.tag())
-    }
-}
-
-impl<P, T, const CP: bool> Deref for TaggedPtr<P, T, CP>
-where
-    P: Pointer,
-    T: Tag,
-{
-    type Target = P::Target;
-
-    #[inline]
-    fn deref(&self) -> &Self::Target {
-        self.raw.deref()
-    }
-}
-
-impl<P, T, const CP: bool> DerefMut for TaggedPtr<P, T, CP>
-where
-    P: Pointer + DerefMut,
-    T: Tag,
-{
-    #[inline]
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        self.raw.deref_mut()
-    }
-}
-
-impl<P, T, const CP: bool> Drop for TaggedPtr<P, T, CP>
-where
-    P: Pointer,
-    T: Tag,
-{
-    fn drop(&mut self) {
-        // No need to drop the tag, as it's Copy
-        unsafe {
-            drop(P::from_ptr(self.raw.pointer_raw()));
-        }
-    }
-}
-
-impl<P, T, const CP: bool> fmt::Debug for TaggedPtr<P, T, CP>
-where
-    P: Pointer + fmt::Debug,
-    T: Tag + fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.raw.with_pointer_ref(|ptr| {
-            f.debug_struct("TaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish()
-        })
-    }
-}
-
-impl<P, T> PartialEq for TaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-    #[inline]
-    fn eq(&self, other: &Self) -> bool {
-        self.raw.eq(&other.raw)
-    }
-}
-
-impl<P, T> Eq for TaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-}
-
-impl<P, T> Hash for TaggedPtr<P, T, true>
-where
-    P: Pointer,
-    T: Tag,
-{
-    #[inline]
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.raw.hash(state);
-    }
-}
-
-impl<P, T, HCX, const CP: bool> HashStable<HCX> for TaggedPtr<P, T, CP>
-where
-    P: Pointer + HashStable<HCX>,
-    T: Tag + HashStable<HCX>,
-{
-    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
-        self.raw.hash_stable(hcx, hasher);
-    }
-}
-
-/// Test that `new` does not compile if there is not enough alignment for the
-/// tag in the pointer.
-///
-/// ```compile_fail,E0080
-/// use rustc_data_structures::tagged_ptr::{TaggedPtr, Tag};
-///
-/// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
-///
-/// unsafe impl Tag for Tag2 {
-///     const BITS: u32 = 2;
-///
-///     fn into_usize(self) -> usize { todo!() }
-///     unsafe fn from_usize(tag: usize) -> Self { todo!() }
-/// }
-///
-/// let value = 12u16;
-/// let reference = &value;
-/// let tag = Tag2::B01;
-///
-/// let _ptr = TaggedPtr::<_, _, true>::new(reference, tag);
-/// ```
-// For some reason miri does not get the compile error
-// probably it `check`s instead of `build`ing?
-#[cfg(not(miri))]
-const _: () = ();
-
-#[cfg(test)]
-mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs
deleted file mode 100644
index 4d342c72cc5..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-use std::ptr;
-use std::sync::Arc;
-
-use crate::tagged_ptr::{Pointer, Tag, Tag2, TaggedPtr};
-
-#[test]
-fn smoke() {
-    let value = 12u32;
-    let reference = &value;
-    let tag = Tag2::B01;
-
-    let ptr = tag_ptr(reference, tag);
-
-    assert_eq!(ptr.tag(), tag);
-    assert_eq!(*ptr, 12);
-
-    let clone = ptr.clone();
-    assert_eq!(clone.tag(), tag);
-    assert_eq!(*clone, 12);
-
-    let mut ptr = ptr;
-    ptr.set_tag(Tag2::B00);
-    assert_eq!(ptr.tag(), Tag2::B00);
-
-    assert_eq!(clone.tag(), tag);
-    assert_eq!(*clone, 12);
-    assert!(ptr::eq(&*ptr, &*clone))
-}
-
-#[test]
-fn boxed() {
-    let value = 12u32;
-    let boxed = Box::new(value);
-    let tag = Tag2::B01;
-
-    let ptr = tag_ptr(boxed, tag);
-
-    assert_eq!(ptr.tag(), tag);
-    assert_eq!(*ptr, 12);
-
-    let clone = ptr.clone();
-    assert_eq!(clone.tag(), tag);
-    assert_eq!(*clone, 12);
-
-    let mut ptr = ptr;
-    ptr.set_tag(Tag2::B00);
-    assert_eq!(ptr.tag(), Tag2::B00);
-
-    assert_eq!(clone.tag(), tag);
-    assert_eq!(*clone, 12);
-    assert!(!ptr::eq(&*ptr, &*clone))
-}
-
-#[test]
-fn arclones() {
-    let value = 12u32;
-    let arc = Arc::new(value);
-    let tag = Tag2::B01;
-
-    let ptr = tag_ptr(arc, tag);
-
-    assert_eq!(ptr.tag(), tag);
-    assert_eq!(*ptr, 12);
-
-    let clone = ptr.clone();
-    assert!(ptr::eq(&*ptr, &*clone))
-}
-
-/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter.
-fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> TaggedPtr<P, T, true> {
-    TaggedPtr::new(ptr, tag)
-}
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs
deleted file mode 100644
index f17a0bf26d7..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-/// Implements [`Tag`] for a given type.
-///
-/// You can use `impl_tag` on structs and enums.
-/// You need to specify the type and all its possible values,
-/// which can only be paths with optional fields.
-///
-/// [`Tag`]: crate::tagged_ptr::Tag
-///
-/// # Examples
-///
-/// Basic usage:
-///
-/// ```
-/// #![feature(macro_metavar_expr)]
-/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag};
-///
-/// #[derive(Copy, Clone, PartialEq, Debug)]
-/// enum SomeTag {
-///     A,
-///     B,
-///     X { v: bool },
-///     Y(bool, bool),
-/// }
-///
-/// impl_tag! {
-///     // The type for which the `Tag` will be implemented
-///     impl Tag for SomeTag;
-///     // You need to specify all possible tag values:
-///     SomeTag::A, // 0
-///     SomeTag::B, // 1
-///     // For variants with fields, you need to specify the fields:
-///     SomeTag::X { v: true  }, // 2
-///     SomeTag::X { v: false }, // 3
-///     // For tuple variants use named syntax:
-///     SomeTag::Y { 0: true,  1: true  }, // 4
-///     SomeTag::Y { 0: false, 1: true  }, // 5
-///     SomeTag::Y { 0: true,  1: false }, // 6
-///     SomeTag::Y { 0: false, 1: false }, // 7
-/// }
-///
-/// // Tag values are assigned in order:
-/// assert_eq!(SomeTag::A.into_usize(), 0);
-/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3);
-/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5);
-///
-/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B);
-/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true });
-/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false));
-/// ```
-///
-/// Structs are supported:
-///
-/// ```
-/// #![feature(macro_metavar_expr)]
-/// # use rustc_data_structures::impl_tag;
-/// #[derive(Copy, Clone)]
-/// struct Flags { a: bool, b: bool }
-///
-/// impl_tag! {
-///     impl Tag for Flags;
-///     Flags { a: true,  b: true  },
-///     Flags { a: false, b: true  },
-///     Flags { a: true,  b: false },
-///     Flags { a: false, b: false },
-/// }
-/// ```
-///
-/// Not specifying all values results in a compile error:
-///
-/// ```compile_fail,E0004
-/// #![feature(macro_metavar_expr)]
-/// # use rustc_data_structures::impl_tag;
-/// #[derive(Copy, Clone)]
-/// enum E {
-///     A,
-///     B,
-/// }
-///
-/// impl_tag! {
-///     impl Tag for E;
-///     E::A,
-/// }
-/// ```
-#[macro_export]
-macro_rules! impl_tag {
-    (
-        impl Tag for $Self:ty;
-        $(
-            $($path:ident)::* $( { $( $fields:tt )* })?,
-        )*
-    ) => {
-        // Safety:
-        // `bits_for_tags` is called on the same `${index()}`-es as
-        // `into_usize` returns, thus `BITS` constant is correct.
-        unsafe impl $crate::tagged_ptr::Tag for $Self {
-            const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[
-                $(
-                    ${index()},
-                    $( ${ignore($path)} )*
-                )*
-            ]);
-
-            #[inline]
-            fn into_usize(self) -> usize {
-                // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc)
-                // (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>)
-                #[forbid(unreachable_patterns)]
-                match self {
-                    // `match` is doing heavy lifting here, by requiring exhaustiveness
-                    $(
-                        $($path)::* $( { $( $fields )* } )? => ${index()},
-                    )*
-                }
-            }
-
-            #[inline]
-            unsafe fn from_usize(tag: usize) -> Self {
-                match tag {
-                    $(
-                        ${index()} => $($path)::* $( { $( $fields )* } )?,
-                    )*
-
-                    // Safety:
-                    // `into_usize` only returns `${index()}` of the same
-                    // repetition as we are filtering above, thus if this is
-                    // reached, the safety contract of this function was
-                    // already breached.
-                    _ => unsafe {
-                        debug_assert!(
-                            false,
-                            "invalid tag: {tag}\
-                             (this is a bug in the caller of `from_usize`)"
-                        );
-                        std::hint::unreachable_unchecked()
-                    },
-                }
-            }
-
-        }
-    };
-}
-
-#[cfg(test)]
-mod tests;
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs
deleted file mode 100644
index 62c926153e1..00000000000
--- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-#[test]
-fn bits_constant() {
-    use crate::tagged_ptr::Tag;
-
-    #[derive(Copy, Clone)]
-    struct Unit;
-    impl_tag! { impl Tag for Unit; Unit, }
-    assert_eq!(Unit::BITS, 0);
-
-    #[derive(Copy, Clone)]
-    enum Enum3 {
-        A,
-        B,
-        C,
-    }
-    impl_tag! { impl Tag for Enum3; Enum3::A, Enum3::B, Enum3::C, }
-    assert_eq!(Enum3::BITS, 2);
-
-    #[derive(Copy, Clone)]
-    struct Eight(bool, bool, bool);
-    impl_tag! {
-        impl Tag for Eight;
-        Eight { 0: true,  1: true,  2: true  },
-        Eight { 0: true,  1: true,  2: false },
-        Eight { 0: true,  1: false, 2: true  },
-        Eight { 0: true,  1: false, 2: false },
-        Eight { 0: false, 1: true,  2: true  },
-        Eight { 0: false, 1: true,  2: false },
-        Eight { 0: false, 1: false, 2: true  },
-        Eight { 0: false, 1: false, 2: false },
-    }
-
-    assert_eq!(Eight::BITS, 3);
-}
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
new file mode 100644
index 00000000000..b1bdee18d6d
--- /dev/null
+++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs
@@ -0,0 +1,105 @@
+use std::ptr;
+
+use super::*;
+use crate::hashes::Hash128;
+use crate::stable_hasher::{HashStable, StableHasher};
+
+/// A tag type used in [`TaggedRef`] tests.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum Tag2 {
+    B00 = 0b00,
+    B01 = 0b01,
+    B10 = 0b10,
+    B11 = 0b11,
+}
+
+unsafe impl Tag for Tag2 {
+    const BITS: u32 = 2;
+
+    fn into_usize(self) -> usize {
+        self as _
+    }
+
+    unsafe fn from_usize(tag: usize) -> Self {
+        match tag {
+            0b00 => Tag2::B00,
+            0b01 => Tag2::B01,
+            0b10 => Tag2::B10,
+            0b11 => Tag2::B11,
+            _ => unreachable!(),
+        }
+    }
+}
+
+impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 {
+    fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) {
+        (*self as u8).hash_stable(hcx, hasher);
+    }
+}
+
+#[test]
+fn smoke() {
+    let value = 12u32;
+    let reference = &value;
+    let tag = Tag2::B01;
+
+    let ptr = TaggedRef::new(reference, tag);
+
+    assert_eq!(ptr.tag(), tag);
+    assert_eq!(*ptr, 12);
+    assert!(ptr::eq(ptr.pointer(), reference));
+
+    let copy = ptr;
+
+    let mut ptr = ptr;
+    ptr.set_tag(Tag2::B00);
+    assert_eq!(ptr.tag(), Tag2::B00);
+
+    assert_eq!(copy.tag(), tag);
+    assert_eq!(*copy, 12);
+    assert!(ptr::eq(copy.pointer(), reference));
+}
+
+#[test]
+fn stable_hash_hashes_as_tuple() {
+    let hash_packed = {
+        let mut hasher = StableHasher::new();
+        TaggedRef::new(&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
+        hasher.finish::<Hash128>()
+    };
+
+    let hash_tupled = {
+        let mut hasher = StableHasher::new();
+        (&12, Tag2::B11).hash_stable(&mut (), &mut hasher);
+        hasher.finish::<Hash128>()
+    };
+
+    assert_eq!(hash_packed, hash_tupled);
+}
+
+/// Test that `new` does not compile if there is not enough alignment for the
+/// tag in the pointer.
+///
+/// ```compile_fail,E0080
+/// use rustc_data_structures::tagged_ptr::{TaggedRef, Tag};
+///
+/// #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
+///
+/// unsafe impl Tag for Tag2 {
+///     const BITS: u32 = 2;
+///
+///     fn into_usize(self) -> usize { todo!() }
+///     unsafe fn from_usize(tag: usize) -> Self { todo!() }
+/// }
+///
+/// let value = 12u16;
+/// let reference = &value;
+/// let tag = Tag2::B01;
+///
+/// let _ptr = TaggedRef::<_, _, true>::new(reference, tag);
+/// ```
+// For some reason miri does not get the compile error
+// probably it `check`s instead of `build`ing?
+#[cfg(not(miri))]
+const _: () = ();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 2f4b42587fb..46eed2db236 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2460,16 +2460,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             spans.push_span_label(
                                 param.span,
                                 format!(
-                                    "{} {} to match the {} type of this parameter",
+                                    "{} need{} to match the {} type of this parameter",
                                     display_list_with_comma_and(&other_param_matched_names),
-                                    format!(
-                                        "need{}",
-                                        pluralize!(if other_param_matched_names.len() == 1 {
-                                            0
-                                        } else {
-                                            1
-                                        })
-                                    ),
+                                    pluralize!(if other_param_matched_names.len() == 1 {
+                                        0
+                                    } else {
+                                        1
+                                    }),
                                     matched_ty,
                                 ),
                             );
diff --git a/compiler/rustc_lint/src/unqualified_local_imports.rs b/compiler/rustc_lint/src/unqualified_local_imports.rs
index c9dd6b32d88..b27398a950c 100644
--- a/compiler/rustc_lint/src/unqualified_local_imports.rs
+++ b/compiler/rustc_lint/src/unqualified_local_imports.rs
@@ -12,6 +12,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,edition2018
+    /// #![feature(unqualified_local_imports)]
     /// #![warn(unqualified_local_imports)]
     ///
     /// mod localmod {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 8399f4c12f4..0c6147f4a46 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2671,6 +2671,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
+    /// #![feature(strict_provenance_lints)]
     /// #![warn(fuzzy_provenance_casts)]
     ///
     /// fn main() {
@@ -2714,6 +2715,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
+    /// #![feature(strict_provenance_lints)]
     /// #![warn(lossy_provenance_casts)]
     ///
     /// fn main() {
@@ -4033,6 +4035,8 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
+    /// // This lint is intentionally used to test the compiler's behavior
+    /// // when an unstable lint is enabled without the corresponding feature gate.
     /// #![allow(test_unstable_lint)]
     /// ```
     ///
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 30a5586f59c..6718493f6b3 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -21,7 +21,7 @@ use crate::arena::Arena;
 ///   pointer.
 /// - Because of this, you cannot get a `List<T>` that is a sub-list of another
 ///   `List<T>`. You can get a sub-slice `&[T]`, however.
-/// - `List<T>` can be used with `CopyTaggedPtr`, which is useful within
+/// - `List<T>` can be used with `TaggedRef`, which is useful within
 ///   structs whose size must be minimized.
 /// - Because of the uniqueness assumption, we can use the address of a
 ///   `List<T>` for faster equality comparisons and hashing.
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 84e43d0e016..7998596c59e 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -347,7 +347,7 @@ pub fn strip_generics_from_path(path_str: &str) -> Result<Box<str>, MalformedGen
 
 /// Returns whether the first doc-comment is an inner attribute.
 ///
-//// If there are no doc-comments, return true.
+/// If there are no doc-comments, return true.
 /// FIXME(#78591): Support both inner and outer attributes on the same item.
 pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
     attrs
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 6ee3907cc8e..c000fd6f4ef 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -48,8 +48,8 @@ macro_rules! vec {
     );
     ($($x:expr),+ $(,)?) => (
         <[_]>::into_vec(
-            // Using the intrinsic produces a dramatic improvement in compile
-            // time when constructing arrays with many elements.
+            // Using the intrinsic produces a dramatic improvement in stack usage for
+            // unoptimized programs using this code path to construct large Vecs.
             $crate::boxed::box_new([$($x),+])
         )
     );
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index fe7e4a77f71..c3375b69961 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -386,13 +386,37 @@ impl Step for CI {
         let library_clippy_cfg = LintConfig {
             allow: vec!["clippy::all".into()],
             warn: vec![],
-            deny: vec!["clippy::correctness".into()],
+            deny: vec![
+                "clippy::correctness".into(),
+                "clippy::char_lit_as_u8".into(),
+                "clippy::four_forward_slashes".into(),
+                "clippy::needless_bool".into(),
+                "clippy::needless_bool_assign".into(),
+                "clippy::non_minimal_cfg".into(),
+                "clippy::print_literal".into(),
+                "clippy::same_item_push".into(),
+                "clippy::single_char_add_str".into(),
+                "clippy::to_string_in_format_args".into(),
+            ],
             forbid: vec![],
         };
         let compiler_clippy_cfg = LintConfig {
             allow: vec!["clippy::all".into()],
             warn: vec![],
-            deny: vec!["clippy::correctness".into(), "clippy::clone_on_ref_ptr".into()],
+            deny: vec![
+                "clippy::correctness".into(),
+                "clippy::char_lit_as_u8".into(),
+                "clippy::clone_on_ref_ptr".into(),
+                "clippy::format_in_format_args".into(),
+                "clippy::four_forward_slashes".into(),
+                "clippy::needless_bool".into(),
+                "clippy::needless_bool_assign".into(),
+                "clippy::non_minimal_cfg".into(),
+                "clippy::print_literal".into(),
+                "clippy::same_item_push".into(),
+                "clippy::single_char_add_str".into(),
+                "clippy::to_string_in_format_args".into(),
+            ],
             forbid: vec![],
         };
 
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 7a95d33723e..cbb3ce6abe6 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -140,6 +140,7 @@ struct CacheBuilder<'a, 'tcx> {
     /// This field is used to prevent duplicated impl blocks.
     impl_ids: DefIdMap<DefIdSet>,
     tcx: TyCtxt<'tcx>,
+    is_json_output: bool,
 }
 
 impl Cache {
@@ -184,8 +185,13 @@ impl Cache {
         }
 
         let (krate, mut impl_ids) = {
-            let mut cache_builder =
-                CacheBuilder { tcx, cache: &mut cx.cache, impl_ids: Default::default() };
+            let is_json_output = cx.is_json_output();
+            let mut cache_builder = CacheBuilder {
+                tcx,
+                cache: &mut cx.cache,
+                impl_ids: Default::default(),
+                is_json_output,
+            };
             krate = cache_builder.fold_crate(krate);
             (krate, cache_builder.impl_ids)
         };
@@ -307,12 +313,13 @@ impl DocFolder for CacheBuilder<'_, '_> {
             | clean::ProcMacroItem(..)
             | clean::VariantItem(..) => {
                 use rustc_data_structures::fx::IndexEntry as Entry;
-                if !self.cache.stripped_mod
-                    && !matches!(
-                        item.stability.map(|stab| stab.level),
-                        Some(StabilityLevel::Stable { allowed_through_unstable_modules: true, .. })
-                    )
-                {
+
+                let skip_because_unstable = matches!(
+                    item.stability.map(|stab| stab.level),
+                    Some(StabilityLevel::Stable { allowed_through_unstable_modules: true, .. })
+                );
+
+                if (!self.cache.stripped_mod && !skip_because_unstable) || self.is_json_output {
                     // Re-exported items mean that the same id can show up twice
                     // in the rustdoc ast that we're looking at. We know,
                     // however, that a re-exported item doesn't show up in the
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index b6a1d7dfa7a..7bfa7e3355d 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -65,6 +65,11 @@ enum CommandKind {
     /// Checks the path doesn't exist.
     HasNotPath,
 
+    /// `//@ !has <path> <value>`
+    ///
+    /// Checks the path exists, but doesn't have the given value.
+    HasNotValue { value: String },
+
     /// `//@ is <path> <value>`
     ///
     /// Check the path is the given value.
@@ -128,10 +133,11 @@ impl CommandKind {
                 [_path, value] => Self::HasValue { value: value.clone() },
                 _ => panic!("`//@ has` must have 2 or 3 arguments, but got {args:?}"),
             },
-            ("has", true) => {
-                assert_eq!(args.len(), 1, "args={args:?}");
-                Self::HasNotPath
-            }
+            ("has", true) => match args {
+                [_path] => Self::HasNotPath,
+                [_path, value] => Self::HasNotValue { value: value.clone() },
+                _ => panic!("`//@ !has` must have 2 or 3 arguments, but got {args:?}"),
+            },
 
             (_, false) if KNOWN_DIRECTIVE_NAMES.contains(&command_name) => {
                 return None;
@@ -223,6 +229,19 @@ fn check_command(command: &Command, cache: &mut Cache) -> Result<(), String> {
                 return Err(format!("matched to {matches:?}, which didn't contain {want_value:?}"));
             }
         }
+        CommandKind::HasNotValue { value } => {
+            let wantnt_value = string_to_value(value, cache);
+            if matches.contains(&wantnt_value.as_ref()) {
+                return Err(format!(
+                    "matched to {matches:?}, which contains unwanted {wantnt_value:?}"
+                ));
+            } else if matches.is_empty() {
+                return Err(format!(
+                    "got no matches, but expected some matched (not containing {wantnt_value:?}"
+                ));
+            }
+        }
+
         CommandKind::Is { value } => {
             let want_value = string_to_value(value, cache);
             let matched = get_one(&matches)?;
diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs
index f7c752033c5..791b231c27a 100644
--- a/src/tools/jsondoclint/src/validator.rs
+++ b/src/tools/jsondoclint/src/validator.rs
@@ -303,6 +303,12 @@ impl<'a> Validator<'a> {
             PathKind::Trait => self.add_trait_or_alias_id(&x.id),
             PathKind::Type => self.add_type_id(&x.id),
         }
+
+        // FIXME: More robust support for checking things in $.index also exist in $.paths
+        if !self.krate.paths.contains_key(&x.id) {
+            self.fail(&x.id, ErrorKind::Custom(format!("No entry in '$.paths' for {x:?}")));
+        }
+
         if let Some(args) = &x.args {
             self.check_generic_args(&**args);
         }
diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs
index e842e1318db..7fcb8ffd1f9 100644
--- a/src/tools/jsondoclint/src/validator/tests.rs
+++ b/src/tools/jsondoclint/src/validator/tests.rs
@@ -1,5 +1,5 @@
 use rustc_hash::FxHashMap;
-use rustdoc_json_types::{FORMAT_VERSION, Item, ItemKind, Visibility};
+use rustdoc_json_types::{Abi, FORMAT_VERSION, FunctionHeader, Item, ItemKind, Visibility};
 
 use super::*;
 use crate::json_find::SelectorPart;
@@ -103,6 +103,101 @@ fn errors_on_local_in_paths_and_not_index() {
 }
 
 #[test]
+fn errors_on_missing_path() {
+    // crate-name=foo
+    // ```
+    // pub struct Bar;
+    // pub fn mk_bar() -> Bar { ... }
+    // ```
+
+    let generics = Generics { params: vec![], where_predicates: vec![] };
+
+    let krate = Crate {
+        root: Id(0),
+        crate_version: None,
+        includes_private: false,
+        index: FxHashMap::from_iter([
+            (Id(0), Item {
+                id: Id(0),
+                crate_id: 0,
+                name: Some("foo".to_owned()),
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: FxHashMap::default(),
+                attrs: Vec::new(),
+                deprecation: None,
+                inner: ItemEnum::Module(Module {
+                    is_crate: true,
+                    items: vec![Id(1), Id(2)],
+                    is_stripped: false,
+                }),
+            }),
+            (Id(1), Item {
+                id: Id(0),
+                crate_id: 0,
+                name: Some("Bar".to_owned()),
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: FxHashMap::default(),
+                attrs: Vec::new(),
+                deprecation: None,
+                inner: ItemEnum::Struct(Struct {
+                    kind: StructKind::Unit,
+                    generics: generics.clone(),
+                    impls: vec![],
+                }),
+            }),
+            (Id(2), Item {
+                id: Id(0),
+                crate_id: 0,
+                name: Some("mk_bar".to_owned()),
+                span: None,
+                visibility: Visibility::Public,
+                docs: None,
+                links: FxHashMap::default(),
+                attrs: Vec::new(),
+                deprecation: None,
+                inner: ItemEnum::Function(Function {
+                    sig: FunctionSignature {
+                        inputs: vec![],
+                        output: Some(Type::ResolvedPath(Path {
+                            name: "Bar".to_owned(),
+                            id: Id(1),
+                            args: None,
+                        })),
+                        is_c_variadic: false,
+                    },
+                    generics,
+                    header: FunctionHeader {
+                        is_const: false,
+                        is_unsafe: false,
+                        is_async: false,
+                        abi: Abi::Rust,
+                    },
+                    has_body: true,
+                }),
+            }),
+        ]),
+        paths: FxHashMap::from_iter([(Id(0), ItemSummary {
+            crate_id: 0,
+            path: vec!["foo".to_owned()],
+            kind: ItemKind::Module,
+        })]),
+        external_crates: FxHashMap::default(),
+        format_version: rustdoc_json_types::FORMAT_VERSION,
+    };
+
+    check(&krate, &[Error {
+        kind: ErrorKind::Custom(
+            r#"No entry in '$.paths' for Path { name: "Bar", id: Id(1), args: None }"#.to_owned(),
+        ),
+        id: Id(1),
+    }]);
+}
+
+#[test]
 #[should_panic = "LOCAL_CRATE_ID is wrong"]
 fn checks_local_crate_id_is_correct() {
     let krate = Crate {
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 819bbc161e6..ffd4ca22a00 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -6,6 +6,7 @@
 // We want to control use declaration ordering and spacing (and preserve use group comments), so
 // skip rustfmt on this file.
 #![cfg_attr(rustfmt, rustfmt::skip)]
+#![warn(unreachable_pub)]
 
 mod command;
 mod macros;
diff --git a/tests/rustdoc-json/reexport/simple_private.rs b/tests/rustdoc-json/reexport/simple_private.rs
index 8a936f5da1b..405d57d342e 100644
--- a/tests/rustdoc-json/reexport/simple_private.rs
+++ b/tests/rustdoc-json/reexport/simple_private.rs
@@ -12,3 +12,9 @@ mod inner {
 pub use inner::Public;
 
 //@ ismany "$.index[*][?(@.name=='simple_private')].inner.module.items[*]" $use_id
+
+// Test for https://github.com/rust-lang/rust/issues/135309
+//@ has  "$.paths[*][?(@.kind=='module')].path" '["simple_private"]'
+//@ !has "$.paths[*].path"                      '["simple_private", "inner"]'
+//@ has  "$.paths[*][?(@.kind=='struct')].path" '["simple_private", "inner", "Public"]'
+//@ !has "$.paths[*].path"                      '["simple_private", "Public"]'
diff --git a/tests/rustdoc-json/reexport/simple_public.rs b/tests/rustdoc-json/reexport/simple_public.rs
index e5a8dc7d2ad..f1335828314 100644
--- a/tests/rustdoc-json/reexport/simple_public.rs
+++ b/tests/rustdoc-json/reexport/simple_public.rs
@@ -14,3 +14,8 @@ pub mod inner {
 pub use inner::Public;
 
 //@ ismany "$.index[*][?(@.name=='simple_public')].inner.module.items[*]" $import_id $inner_id
+
+//@ has  "$.paths[*][?(@.kind=='module')].path" '["simple_public"]'
+//@ has  "$.paths[*][?(@.kind=='module')].path" '["simple_public", "inner"]'
+//@ has  "$.paths[*][?(@.kind=='struct')].path" '["simple_public", "inner", "Public"]'
+//@ !has "$.paths[*].path"                      '["simple_public", "Public"]'
diff --git a/tests/rustdoc-ui/crate-reference-in-block-module.stderr b/tests/rustdoc-ui/crate-reference-in-block-module.stderr
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/tests/rustdoc-ui/crate-reference-in-block-module.stderr
+++ /dev/null
diff --git a/tests/rustdoc-ui/macro-docs.stdout b/tests/rustdoc-ui/macro-docs.stdout
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/tests/rustdoc-ui/macro-docs.stdout
+++ /dev/null