From 64e7fd952243b6724dcd4e14e177c3e972b342bc Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Sun, 2 Oct 2022 22:08:54 +0000
Subject: [PATCH 1/9] Slightly tweak comments wrt
 `lint_overflowing_range_endpoint`

---
 compiler/rustc_lint/src/types.rs | 78 ++++++++++++++++----------------
 1 file changed, 40 insertions(+), 38 deletions(-)

diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index b6009bd800a5f..3cdca2178657d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -116,8 +116,8 @@ impl TypeLimits {
     }
 }
 
-/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint.
-/// Returns `true` iff the lint was overridden.
+/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint (`expr..MAX+1`).
+/// Returns `true` iff the lint was emitted.
 fn lint_overflowing_range_endpoint<'tcx>(
     cx: &LateContext<'tcx>,
     lit: &hir::Lit,
@@ -140,44 +140,46 @@ fn lint_overflowing_range_endpoint<'tcx>(
         return false;
     }
 
-    let mut overwritten = false;
     // We can suggest using an inclusive range
     // (`..=`) instead only if it is the `end` that is
     // overflowing and only by 1.
-    if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max
-        && let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span)
-    {
-        cx.struct_span_lint(
-            OVERFLOWING_LITERALS,
-            struct_expr.span,
-            fluent::lint::range_endpoint_out_of_range,
-            |lint| {
-                use ast::{LitIntType, LitKind};
-
-                lint.set_arg("ty", ty);
-
-                // We need to preserve the literal's suffix,
-                // as it may determine typing information.
-                let suffix = match lit.node {
-                    LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
-                    LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
-                    LitKind::Int(_, LitIntType::Unsuffixed) => "",
-                    _ => bug!(),
-                };
-                let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
-                lint.span_suggestion(
-                    struct_expr.span,
-                    fluent::lint::suggestion,
-                    suggestion,
-                    Applicability::MachineApplicable,
-                );
-                overwritten = true;
+    if !(eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max) {
+        return false;
+    };
+    let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false };
 
-                lint
-            },
-        );
-    }
-    overwritten
+    cx.struct_span_lint(
+        OVERFLOWING_LITERALS,
+        struct_expr.span,
+        fluent::lint::range_endpoint_out_of_range,
+        |lint| {
+            use ast::{LitIntType, LitKind};
+
+            lint.set_arg("ty", ty);
+
+            // We need to preserve the literal's suffix,
+            // as it may determine typing information.
+            let suffix = match lit.node {
+                LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+                LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+                LitKind::Int(_, LitIntType::Unsuffixed) => "",
+                _ => bug!(),
+            };
+            let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+            lint.span_suggestion(
+                struct_expr.span,
+                fluent::lint::suggestion,
+                suggestion,
+                Applicability::MachineApplicable,
+            );
+
+            lint
+        },
+    );
+
+    // We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
+    // return `true` so the callers don't also emit a lint
+    true
 }
 
 // For `isize` & `usize`, be conservative with the warnings, so that the
@@ -358,7 +360,7 @@ fn lint_int_literal<'tcx>(
         }
 
         if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
-            // The overflowing literal lint was overridden.
+            // The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
             return;
         }
 
@@ -427,7 +429,7 @@ fn lint_uint_literal<'tcx>(
             }
         }
         if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
-            // The overflowing literal lint was overridden.
+            // The overflowing literal lint was emited by `lint_overflowing_range_endpoint`.
             return;
         }
         if let Some(repr_str) = get_bin_hex_repr(cx, lit) {

From 2cc4a0aad72752a4d485ced76bab677620f088b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?=
 <liehr.exchange@gmx.net>
Date: Tue, 18 Oct 2022 15:34:41 +0200
Subject: [PATCH 2/9] rustdoc: render bounds of cross-crate GAT params

---
 src/librustdoc/clean/mod.rs                   | 44 +++++++++++++------
 .../assoc_item_trait_bounds.out0.html         |  1 +
 .../assoc_item_trait_bounds.out2.html         |  1 +
 ...html => assoc_item_trait_bounds.out9.html} |  0
 ...bindings.rs => assoc_item_trait_bounds.rs} | 15 ++++---
 ..._item_trait_bounds_with_bindings.out0.html |  1 -
 ...bindings.rs => assoc_item_trait_bounds.rs} |  1 +
 7 files changed, 41 insertions(+), 22 deletions(-)
 create mode 100644 src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html
 create mode 100644 src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html
 rename src/test/rustdoc/inline_cross/{assoc_item_trait_bounds_with_bindings.out9.html => assoc_item_trait_bounds.out9.html} (100%)
 rename src/test/rustdoc/inline_cross/{assoc_item_trait_bounds_with_bindings.rs => assoc_item_trait_bounds.rs} (79%)
 delete mode 100644 src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
 rename src/test/rustdoc/inline_cross/auxiliary/{assoc_item_trait_bounds_with_bindings.rs => assoc_item_trait_bounds.rs} (96%)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 5f674ed7441ba..13d63ffa0ee3c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1201,21 +1201,19 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
             }
 
             if let ty::TraitContainer = assoc_item.container {
-                // FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs,
-                //                e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in
-                //                `type Assoc<T: Copy> where T: Display`. This also means that we
-                //                later incorrectly render `where T: ?Sized`.
-                //
-                //                The result of `tcx.explicit_predicates_of` *does* contain them but
-                //                it does not contain the other bounds / predicates we need.
-                //                Either merge those two interned lists somehow or refactor
-                //                `clean_ty_generics` to call `explicit_item_bounds` by itself.
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id);
-                let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
-                let mut generics =
-                    clean_ty_generics(cx, tcx.generics_of(assoc_item.def_id), predicates);
-                // Filter out the bounds that are (likely?) directly attached to the associated type,
-                // as opposed to being located in the where clause.
+                let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
+                let predicates =
+                    tcx.arena.alloc_from_iter(bounds.into_iter().chain(predicates).copied());
+                let mut generics = clean_ty_generics(
+                    cx,
+                    tcx.generics_of(assoc_item.def_id),
+                    ty::GenericPredicates { parent: None, predicates },
+                );
+                // Move bounds that are (likely) directly attached to the associated type
+                // from the where clause to the associated type.
+                // There is no guarantee that this is what the user actually wrote but we have
+                // no way of knowing.
                 let mut bounds = generics
                     .where_predicates
                     .drain_filter(|pred| match *pred {
@@ -1273,6 +1271,24 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
                     }
                     None => bounds.push(GenericBound::maybe_sized(cx)),
                 }
+                // Move bounds that are (likely) directly attached to the parameters of the
+                // (generic) associated type from the where clause to the respective parameter.
+                // There is no guarantee that this is what the user actually wrote but we have
+                // no way of knowing.
+                let mut where_predicates = Vec::new();
+                for mut pred in generics.where_predicates {
+                    if let WherePredicate::BoundPredicate { ty: Generic(arg), bounds, .. } = &mut pred
+                    && let Some(GenericParamDef {
+                        kind: GenericParamDefKind::Type { bounds: param_bounds, .. },
+                        ..
+                    }) = generics.params.iter_mut().find(|param| &param.name == arg)
+                    {
+                        param_bounds.extend(mem::take(bounds));
+                    } else {
+                        where_predicates.push(pred);
+                    }
+                }
+                generics.where_predicates = where_predicates;
 
                 if tcx.impl_defaultness(assoc_item.def_id).has_value() {
                     AssocTypeItem(
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html
new file mode 100644
index 0000000000000..8934bc1ee339c
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds/trait.Support.html" title="trait assoc_item_trait_bounds::Support">Support</a>&lt;Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt;</h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html
new file mode 100644
index 0000000000000..bf330670ed0fa
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html
@@ -0,0 +1 @@
+<h4 class="code-header">type <a href="#associatedtype.Out2" class="associatedtype">Out2</a>&lt;T&gt;: <a class="trait" href="../assoc_item_trait_bounds/trait.Support.html" title="trait assoc_item_trait_bounds::Support">Support</a>&lt;Item = T&gt;</h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html
similarity index 100%
rename from src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html
rename to src/test/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
similarity index 79%
rename from src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
rename to src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
index 00976aa74420f..5f4712aab5b19 100644
--- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs
+++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds.rs
@@ -1,13 +1,10 @@
 // Regression test for issues #77763, #84579 and #102142.
 #![crate_name = "main"]
 
-// aux-build:assoc_item_trait_bounds_with_bindings.rs
+// aux-build:assoc_item_trait_bounds.rs
 // build-aux-docs
 // ignore-cross-compile
-extern crate assoc_item_trait_bounds_with_bindings as aux;
-
-// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters
-//                of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed.
+extern crate assoc_item_trait_bounds as aux;
 
 // @has main/trait.Main.html
 // @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>'
@@ -24,11 +21,15 @@ extern crate assoc_item_trait_bounds_with_bindings as aux;
 // @has - '//*[@id="associatedtype.Out11"]' "type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>"
 // @has - '//*[@id="associatedtype.Out12"]' "type Out12: for<'w> Helper<B<'w> = Cow<'w, str>, A<'w> = bool>"
 // @has - '//*[@id="associatedtype.Out13"]' "type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>"
+// @has - '//*[@id="associatedtype.Out14"]' "type Out14<P: Copy + Eq, Q: ?Sized>"
 //
-// Snapshots: Check that we do not render any where-clauses for those associated types since all of
-// the trait bounds contained within were moved to the bounds of the respective item.
+// Snapshots:
+// Check that we don't render any where-clauses for the following associated types since
+// all corresponding projection equality predicates should have already been re-sugared
+// to associated type bindings:
 //
 // @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]'
+// @snapshot out2 - '//*[@id="associatedtype.Out2"]/*[@class="code-header"]'
 // @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]'
 //
 // @has - '//*[@id="tymethod.make"]' \
diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
deleted file mode 100644
index 927a1a42a1f78..0000000000000
--- a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html
+++ /dev/null
@@ -1 +0,0 @@
-<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds_with_bindings/trait.Support.html" title="trait assoc_item_trait_bounds_with_bindings::Support">Support</a>&lt;Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>&gt;</h4>
\ No newline at end of file
diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
similarity index 96%
rename from src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
rename to src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
index f451b1a0e9920..d326e61daea26 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs
@@ -15,6 +15,7 @@ pub trait Main {
     type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>;
     type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>;
     type Out13: for<'fst, 'snd> Aid<'snd, Result<'fst> = &'fst mut str>;
+    type Out14<P: Copy + Eq, Q: ?Sized>;
 
     fn make<F>(_: F, _: impl FnMut(&str) -> bool)
     where

From f81cd87eeae2b02ebfcf309764cd9e648040b988 Mon Sep 17 00:00:00 2001
From: Finn Bear <finnbearlabs@gmail.com>
Date: Wed, 19 Oct 2022 19:07:45 -0700
Subject: [PATCH 3/9] Copy of #102941.

---
 library/alloc/src/string.rs | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 983376a282be5..9bda7f5dc3735 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -67,7 +67,7 @@ use core::str::Utf8Chunks;
 use crate::borrow::{Cow, ToOwned};
 use crate::boxed::Box;
 use crate::collections::TryReserveError;
-use crate::str::{self, Chars, Utf8Error};
+use crate::str::{self, from_utf8_unchecked_mut, Chars, Utf8Error};
 #[cfg(not(no_global_oom_handling))]
 use crate::str::{from_boxed_utf8_unchecked, FromStr};
 use crate::vec::Vec;
@@ -2691,6 +2691,35 @@ impl From<String> for Box<str> {
     fn from(s: String) -> Box<str> {
         s.into_boxed_str()
     }
+
+    /// Consumes and leaks the `String`, returning a mutable reference to the contents,
+    /// `&'a mut str`.
+    ///
+    /// This is mainly useful for data that lives for the remainder of
+    /// the program's life. Dropping the returned reference will cause a memory
+    /// leak.
+    ///
+    /// It does not reallocate or shrink the `String`,
+    /// so the leaked allocation may include unused capacity that is not part
+    /// of the returned slice.
+    ///
+    /// # Examples
+    ///
+    /// Simple usage:
+    ///
+    /// ```
+    /// #![feature(string_leak)]
+    ///
+    /// let x = String::from("bucket");
+    /// let static_ref: &'static mut str = x.leak();
+    /// assert_eq!(static_ref, "bucket");
+    /// ```
+    #[unstable(feature = "string_leak", issue = "102929")]
+    #[inline]
+    pub fn leak(self) -> &'static mut str {
+        let slice = self.vec.leak();
+        unsafe { from_utf8_unchecked_mut(slice) }
+    }
 }
 
 #[cfg(not(no_global_oom_handling))]

From 4f44d6253d02484400afa315a1f0306f4cf35d16 Mon Sep 17 00:00:00 2001
From: Finn Bear <finnbearlabs@gmail.com>
Date: Wed, 19 Oct 2022 19:15:58 -0700
Subject: [PATCH 4/9] Put fn in the right place.

---
 library/alloc/src/string.rs | 58 ++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 9bda7f5dc3735..209abfac6bbf9 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1849,6 +1849,35 @@ impl String {
         let slice = self.vec.into_boxed_slice();
         unsafe { from_boxed_utf8_unchecked(slice) }
     }
+
+    /// Consumes and leaks the `String`, returning a mutable reference to the contents,
+    /// `&'a mut str`.
+    ///
+    /// This is mainly useful for data that lives for the remainder of
+    /// the program's life. Dropping the returned reference will cause a memory
+    /// leak.
+    ///
+    /// It does not reallocate or shrink the `String`,
+    /// so the leaked allocation may include unused capacity that is not part
+    /// of the returned slice.
+    ///
+    /// # Examples
+    ///
+    /// Simple usage:
+    ///
+    /// ```
+    /// #![feature(string_leak)]
+    ///
+    /// let x = String::from("bucket");
+    /// let static_ref: &'static mut str = x.leak();
+    /// assert_eq!(static_ref, "bucket");
+    /// ```
+    #[unstable(feature = "string_leak", issue = "102929")]
+    #[inline]
+    pub fn leak(self) -> &'static mut str {
+        let slice = self.vec.leak();
+        unsafe { from_utf8_unchecked_mut(slice) }
+    }
 }
 
 impl FromUtf8Error {
@@ -2691,35 +2720,6 @@ impl From<String> for Box<str> {
     fn from(s: String) -> Box<str> {
         s.into_boxed_str()
     }
-
-    /// Consumes and leaks the `String`, returning a mutable reference to the contents,
-    /// `&'a mut str`.
-    ///
-    /// This is mainly useful for data that lives for the remainder of
-    /// the program's life. Dropping the returned reference will cause a memory
-    /// leak.
-    ///
-    /// It does not reallocate or shrink the `String`,
-    /// so the leaked allocation may include unused capacity that is not part
-    /// of the returned slice.
-    ///
-    /// # Examples
-    ///
-    /// Simple usage:
-    ///
-    /// ```
-    /// #![feature(string_leak)]
-    ///
-    /// let x = String::from("bucket");
-    /// let static_ref: &'static mut str = x.leak();
-    /// assert_eq!(static_ref, "bucket");
-    /// ```
-    #[unstable(feature = "string_leak", issue = "102929")]
-    #[inline]
-    pub fn leak(self) -> &'static mut str {
-        let slice = self.vec.leak();
-        unsafe { from_utf8_unchecked_mut(slice) }
-    }
 }
 
 #[cfg(not(no_global_oom_handling))]

From 9b6791078a580acdd05246f00f900cbc079bb95e Mon Sep 17 00:00:00 2001
From: Ben Kimock <kimockb@gmail.com>
Date: Thu, 20 Oct 2022 20:40:35 -0400
Subject: [PATCH 5/9] Add a missing precondition check

---
 library/core/src/ptr/non_null.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index f3ef094cbccc5..7264d57ba6aed 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -2,6 +2,7 @@ use crate::cmp::Ordering;
 use crate::convert::From;
 use crate::fmt;
 use crate::hash;
+use crate::intrinsics::assert_unsafe_precondition;
 use crate::marker::Unsize;
 use crate::mem::{self, MaybeUninit};
 use crate::num::NonZeroUsize;
@@ -195,7 +196,10 @@ impl<T: ?Sized> NonNull<T> {
     #[inline]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         // SAFETY: the caller must guarantee that `ptr` is non-null.
-        unsafe { NonNull { pointer: ptr as _ } }
+        unsafe {
+            assert_unsafe_precondition!([T: ?Sized](ptr: *mut T) => !ptr.is_null());
+            NonNull { pointer: ptr as _ }
+        }
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.

From 71c39dea4d18373e4da35838332071562ea44d33 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@nebumind.com>
Date: Fri, 21 Oct 2022 14:05:45 +0200
Subject: [PATCH 6/9] Argument type for mutable with_metadata_of (#75091)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The method takes two pointer arguments: one `self` supplying the pointer
value, and a second pointer supplying the metadata.

The new parameter type more clearly reflects the actual requirements.
The provenance of the metadata parameter is disregarded completely.
Using a mutable pointer in the call site can be coerced to a const
pointer while the reverse is not true.

An example of the current use:

```rust
// Manually taking an unsized object from a `ManuallyDrop` into another allocation.
let val: &core::mem::ManuallyDrop<T> = …;

let ptr = val as *const _ as *mut T;
let ptr = uninit.as_ptr().with_metadata_of(ptr);
```

This could then instead be simplified to:

```rust
// Manually taking an unsized object from a `ManuallyDrop` into another allocation.
let val: &core::mem::ManuallyDrop<T> = …;

let ptr = uninit.as_ptr().with_metadata_of(&**val);
```
---
 library/core/src/ptr/mut_ptr.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index bbcc7c699e036..0bb2566fd4c98 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -80,10 +80,14 @@ impl<T: ?Sized> *mut T {
     #[unstable(feature = "set_ptr_value", issue = "75091")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
-    pub fn with_metadata_of<U>(self, mut val: *mut U) -> *mut U
+    pub fn with_metadata_of<U>(self, val: *const U) -> *mut U
     where
         U: ?Sized,
     {
+        // Prepare in the type system that we will replace the pointer value with a mutable
+        // pointer, taking the mutable provenance from the `self` pointer.
+        let mut val = val as *mut U;
+        // Pointer to the pointer value within the value.
         let target = &mut val as *mut *mut U as *mut *mut u8;
         // SAFETY: In case of a thin pointer, this operations is identical
         // to a simple assignment. In case of a fat pointer, with the current

From e3606b2b0298be6122d002257b50ba42f0b4d4d2 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@nebumind.com>
Date: Fri, 21 Oct 2022 14:34:16 +0200
Subject: [PATCH 7/9] Reduce mutability in std-use of with_metadata_of

---
 library/alloc/src/rc.rs   | 2 +-
 library/alloc/src/sync.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 6d247681c6661..9c229665c7e91 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1386,7 +1386,7 @@ impl<T: ?Sized> Rc<T> {
             Self::allocate_for_layout(
                 Layout::for_value(&*ptr),
                 |layout| Global.allocate(layout),
-                |mem| mem.with_metadata_of(ptr as *mut RcBox<T>),
+                |mem| mem.with_metadata_of(ptr as *const RcBox<T>),
             )
         }
     }
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index df315dad89324..e8d9de4fb3ce5 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1204,7 +1204,7 @@ impl<T: ?Sized> Arc<T> {
             Self::allocate_for_layout(
                 Layout::for_value(&*ptr),
                 |layout| Global.allocate(layout),
-                |mem| mem.with_metadata_of(ptr as *mut ArcInner<T>),
+                |mem| mem.with_metadata_of(ptr as *const ArcInner<T>),
             )
         }
     }

From d7b0bcb20f2f7d5f3ea3489d56ece630147e98f5 Mon Sep 17 00:00:00 2001
From: Chris Denton <christophersdenton@gmail.com>
Date: Fri, 21 Oct 2022 17:57:22 +0100
Subject: [PATCH 8/9] Reduce false positives in msys2 detection

This checks that:

* the handle is a pipe
* the pipe's file name starts with "msys-" or "cygwin-" rather than looking in the full path.
---
 library/std/src/sys/windows/c.rs  |  3 +++
 library/std/src/sys/windows/io.rs | 11 +++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 917fc8e4995e6..be6fc2ebb7a27 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -129,6 +129,8 @@ pub const FIONBIO: c_ulong = 0x8004667e;
 
 pub const MAX_PATH: usize = 260;
 
+pub const FILE_TYPE_PIPE: u32 = 3;
+
 #[repr(C)]
 #[derive(Copy)]
 pub struct WIN32_FIND_DATAW {
@@ -1114,6 +1116,7 @@ extern "system" {
         lpFileInformation: LPVOID,
         dwBufferSize: DWORD,
     ) -> BOOL;
+    pub fn GetFileType(hfile: HANDLE) -> DWORD;
     pub fn SleepConditionVariableSRW(
         ConditionVariable: PCONDITION_VARIABLE,
         SRWLock: PSRWLOCK,
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index 0879ef199338e..2cc34c986b990 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -120,6 +120,11 @@ unsafe fn handle_is_console(handle: BorrowedHandle<'_>) -> bool {
 }
 
 unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
+    // Early return if the handle is not a pipe.
+    if c::GetFileType(handle) != c::FILE_TYPE_PIPE {
+        return false;
+    }
+
     const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>();
     let mut name_info_bytes = Align8([0u8; SIZE]);
     let res = c::GetFileInformationByHandleEx(
@@ -137,11 +142,13 @@ unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
     let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>();
     let s = core::slice::from_raw_parts(name_ptr, name_len);
     let name = String::from_utf16_lossy(s);
+    // Get the file name only.
+    let name = name.rsplit('\\').next().unwrap_or(&name);
     // This checks whether 'pty' exists in the file name, which indicates that
     // a pseudo-terminal is attached. To mitigate against false positives
     // (e.g., an actual file name that contains 'pty'), we also require that
-    // either the strings 'msys-' or 'cygwin-' are in the file name as well.)
-    let is_msys = name.contains("msys-") || name.contains("cygwin-");
+    // the file name begins with either the strings 'msys-' or 'cygwin-'.)
+    let is_msys = name.starts_with("msys-") || name.starts_with("cygwin-");
     let is_pty = name.contains("-pty");
     is_msys && is_pty
 }

From 10dad22b6669defeee296a91b2e2c92f8fd46e43 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 16 Feb 2022 14:48:39 -0500
Subject: [PATCH 9/9] Only apply `ProceduralMasquerade` hack to older versions
 of `rental`

The latest version of `rental` (v0.5.6) contains a fix that allows it to
compile without relying on the pretty-print back-compat hack.

Hopefully, there are no longer any crates relying on the affected
versions of the (much less popular) `procedural-masquerade` crate. This
should allow us to target the pretty-print back-compat hack specifically
to older versions of `rental`, and specifically mention upgrading to
`rental` v0.5.6 in the lint message.
---
 compiler/rustc_expand/src/base.rs             |  46 +++--
 .../issue-73933-procedural-masquerade.rs      |   9 +-
 .../issue-73933-procedural-masquerade.stderr  |  91 ---------
 .../issue-73933-procedural-masquerade.stdout  |  11 +-
 .../ui/proc-macro/pretty-print-hack-hide.rs   |  12 ++
 .../proc-macro/pretty-print-hack-hide.stdout  |  21 ++
 .../ui/proc-macro/pretty-print-hack-show.rs   |  17 ++
 .../proc-macro/pretty-print-hack-show.stderr  | 179 ++++++++++++++++++
 .../proc-macro/pretty-print-hack-show.stdout  |  44 +++++
 .../allsorts-rental-0.5.6/src/lib.rs          |  14 ++
 .../pretty-print-hack/rental-0.5.5/src/lib.rs |  14 ++
 .../pretty-print-hack/rental-0.5.6/src/lib.rs |  14 ++
 12 files changed, 356 insertions(+), 116 deletions(-)
 delete mode 100644 src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack-hide.rs
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack-hide.stdout
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack-show.rs
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack-show.stderr
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack-show.stdout
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
 create mode 100644 src/test/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs

diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 052ca229f0127..c8de60ccb89b9 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -22,7 +22,7 @@ use rustc_span::edition::Edition;
 use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
+use rustc_span::{BytePos, FileName, RealFileName, Span, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
 use std::default::Default;
@@ -1423,16 +1423,40 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool {
         if let ast::ItemKind::Enum(enum_def, _) = &item.kind {
             if let [variant] = &*enum_def.variants {
                 if variant.ident.name == sym::Input {
-                    sess.buffer_lint_with_diagnostic(
-                        &PROC_MACRO_BACK_COMPAT,
-                        item.ident.span,
-                        ast::CRATE_NODE_ID,
-                        "using `procedural-masquerade` crate",
-                        BuiltinLintDiagnostics::ProcMacroBackCompat(
-                        "The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. \
-                        Versions of this crate below 0.1.7 will eventually stop compiling.".to_string())
-                    );
-                    return true;
+                    let filename = sess.source_map().span_to_filename(item.ident.span);
+                    if let FileName::Real(RealFileName::LocalPath(path)) = filename {
+                        if let Some(c) = path
+                            .components()
+                            .flat_map(|c| c.as_os_str().to_str())
+                            .find(|c| c.starts_with("rental") || c.starts_with("allsorts-rental"))
+                        {
+                            let crate_matches = if c.starts_with("allsorts-rental") {
+                                true
+                            } else {
+                                let mut version = c.trim_start_matches("rental-").split(".");
+                                version.next() == Some("0")
+                                    && version.next() == Some("5")
+                                    && version
+                                        .next()
+                                        .and_then(|c| c.parse::<u32>().ok())
+                                        .map_or(false, |v| v < 6)
+                            };
+
+                            if crate_matches {
+                                sess.buffer_lint_with_diagnostic(
+                                        &PROC_MACRO_BACK_COMPAT,
+                                        item.ident.span,
+                                        ast::CRATE_NODE_ID,
+                                        "using an old version of `rental`",
+                                        BuiltinLintDiagnostics::ProcMacroBackCompat(
+                                        "older versions of the `rental` crate will stop compiling in future versions of Rust; \
+                                        please update to `rental` v0.5.6, or switch to one of the `rental` alternatives".to_string()
+                                        )
+                                    );
+                                return true;
+                            }
+                        }
+                    }
                 }
             }
         }
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs
index 0c1c51c01a884..a573c6e1c0b86 100644
--- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs
+++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.rs
@@ -1,18 +1,11 @@
 // aux-build:test-macros.rs
+// check-pass
 
 #[macro_use]
 extern crate test_macros;
 
 #[derive(Print)]
 enum ProceduralMasqueradeDummyType {
-//~^ ERROR using
-//~| WARN this was previously
-//~| ERROR using
-//~| WARN this was previously
-//~| ERROR using
-//~| WARN this was previously
-//~| ERROR using
-//~| WARN this was previously
     Input
 }
 
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
deleted file mode 100644
index ebb8e825e6a3b..0000000000000
--- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr
+++ /dev/null
@@ -1,91 +0,0 @@
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-
-error: aborting due to 4 previous errors
-
-Future incompatibility report: Future breakage diagnostic:
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
-Future breakage diagnostic:
-error: using `procedural-masquerade` crate
-  --> $DIR/issue-73933-procedural-masquerade.rs:7:6
-   |
-LL | enum ProceduralMasqueradeDummyType {
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
-   = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling.
-   = note: `#[deny(proc_macro_back_compat)]` on by default
-
diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout
index 50334589d0bba..8cd981e03f118 100644
--- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout
+++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stdout
@@ -1,22 +1,21 @@
-PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
-PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
+PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "enum",
-        span: #0 bytes(86..90),
+        span: #0 bytes(100..104),
     },
     Ident {
         ident: "ProceduralMasqueradeDummyType",
-        span: #0 bytes(91..120),
+        span: #0 bytes(105..134),
     },
     Group {
         delimiter: Brace,
         stream: TokenStream [
             Ident {
                 ident: "Input",
-                span: #0 bytes(315..320),
+                span: #0 bytes(141..146),
             },
         ],
-        span: #0 bytes(121..322),
+        span: #0 bytes(135..148),
     },
 ]
diff --git a/src/test/ui/proc-macro/pretty-print-hack-hide.rs b/src/test/ui/proc-macro/pretty-print-hack-hide.rs
new file mode 100644
index 0000000000000..f53e8fe8252f8
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack-hide.rs
@@ -0,0 +1,12 @@
+// aux-build:test-macros.rs
+// compile-flags: -Z span-debug
+// check-pass
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use] extern crate test_macros;
+
+include!("pretty-print-hack/rental-0.5.6/src/lib.rs");
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/pretty-print-hack-hide.stdout b/src/test/ui/proc-macro/pretty-print-hack-hide.stdout
new file mode 100644
index 0000000000000..ea796bb269768
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack-hide.stdout
@@ -0,0 +1,21 @@
+PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
+PRINT-DERIVE INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "enum",
+        span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:1: 4:5 (#0),
+    },
+    Ident {
+        ident: "ProceduralMasqueradeDummyType",
+        span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:6: 4:35 (#0),
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Ident {
+                ident: "Input",
+                span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:13:5: 13:10 (#0),
+            },
+        ],
+        span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:36: 14:2 (#0),
+    },
+]
diff --git a/src/test/ui/proc-macro/pretty-print-hack-show.rs b/src/test/ui/proc-macro/pretty-print-hack-show.rs
new file mode 100644
index 0000000000000..9b1899e49220e
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack-show.rs
@@ -0,0 +1,17 @@
+// aux-build:test-macros.rs
+// compile-flags: -Z span-debug
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use] extern crate test_macros;
+
+mod first {
+    include!("pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs");
+}
+
+mod second {
+    include!("pretty-print-hack/rental-0.5.5/src/lib.rs");
+}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/pretty-print-hack-show.stderr b/src/test/ui/proc-macro/pretty-print-hack-show.stderr
new file mode 100644
index 0000000000000..873054927c962
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack-show.stderr
@@ -0,0 +1,179 @@
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+
+error: aborting due to 8 previous errors
+
+Future incompatibility report: Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
+Future breakage diagnostic:
+error: using an old version of `rental`
+  --> $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6
+   |
+LL | enum ProceduralMasqueradeDummyType {
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+   = note: older versions of the `rental` crate will stop compiling in future versions of Rust; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives
+   = note: `#[deny(proc_macro_back_compat)]` on by default
+
diff --git a/src/test/ui/proc-macro/pretty-print-hack-show.stdout b/src/test/ui/proc-macro/pretty-print-hack-show.stdout
new file mode 100644
index 0000000000000..3d793d2a0145c
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack-show.stdout
@@ -0,0 +1,44 @@
+PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
+PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
+PRINT-DERIVE INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "enum",
+        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:1: 4:5 (#0),
+    },
+    Ident {
+        ident: "ProceduralMasqueradeDummyType",
+        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:6: 4:35 (#0),
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Ident {
+                ident: "Input",
+                span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:13:5: 13:10 (#0),
+            },
+        ],
+        span: $DIR/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs:4:36: 14:2 (#0),
+    },
+]
+PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input, }
+PRINT-DERIVE RE-COLLECTED (DISPLAY): enum ProceduralMasqueradeDummyType { Input }
+PRINT-DERIVE INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "enum",
+        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:1: 4:5 (#0),
+    },
+    Ident {
+        ident: "ProceduralMasqueradeDummyType",
+        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:6: 4:35 (#0),
+    },
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Ident {
+                ident: "Input",
+                span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:13:5: 13:10 (#0),
+            },
+        ],
+        span: $DIR/pretty-print-hack/rental-0.5.5/src/lib.rs:4:36: 14:2 (#0),
+    },
+]
diff --git a/src/test/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs b/src/test/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
new file mode 100644
index 0000000000000..9501980fa55df
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs
@@ -0,0 +1,14 @@
+// ignore-test
+
+#[derive(Print)]
+enum ProceduralMasqueradeDummyType {
+//~^ ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+    Input
+}
diff --git a/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs b/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
new file mode 100644
index 0000000000000..9501980fa55df
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs
@@ -0,0 +1,14 @@
+// ignore-test
+
+#[derive(Print)]
+enum ProceduralMasqueradeDummyType {
+//~^ ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+    Input
+}
diff --git a/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs b/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs
new file mode 100644
index 0000000000000..9501980fa55df
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs
@@ -0,0 +1,14 @@
+// ignore-test
+
+#[derive(Print)]
+enum ProceduralMasqueradeDummyType {
+//~^ ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+//~| ERROR using
+//~| WARN this was previously
+    Input
+}