about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-31 23:30:28 +0000
committerbors <bors@rust-lang.org>2023-07-31 23:30:28 +0000
commit706a4d9a4eb6794f5516f5a67660952c2247e928 (patch)
tree348c6361ca5e64726fcbb1a926f07234fd5bb41c
parentdb7ff98a72f3e742b641f9cb16d0e8c285e87e9b (diff)
parentc73e232d2024b6625da9a17a43641949840d8751 (diff)
downloadrust-706a4d9a4eb6794f5516f5a67660952c2247e928.tar.gz
rust-706a4d9a4eb6794f5516f5a67660952c2247e928.zip
Auto merge of #114308 - matthiaskrgr:rollup-m64bkm7, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #109318 (Make `Debug` representations of `[Lazy, Once]*[Cell, Lock]` consistent with `Mutex` and `RwLock`)
 - #113701 (Re-export core::ffi::FromBytesUntilNulError in std::ffi)
 - #113804 (Resolve correct archive version name in `opt-dist`)
 - #114165 (Add missing rvalues to smir)
 - #114182 (clean up after 113312)
 - #114193 (Update lexer emoji diagnostics to Unicode 15.0)
 - #114200 (Detect trait upcasting through struct tail unsizing in new solver select)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock49
-rw-r--r--compiler/rustc_lexer/Cargo.toml6
-rw-r--r--compiler/rustc_lexer/src/lib.rs11
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs51
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs39
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs25
-rw-r--r--library/core/src/cell/once.rs8
-rw-r--r--library/core/src/fmt/mod.rs20
-rw-r--r--library/std/src/ffi/mod.rs2
-rw-r--r--library/std/src/sync/lazy_lock.rs8
-rw-r--r--library/std/src/sync/mutex.rs8
-rw-r--r--library/std/src/sync/once_lock.rs8
-rw-r--r--library/std/src/sync/rwlock.rs8
-rw-r--r--src/tools/opt-dist/src/tests.rs25
-rw-r--r--src/tools/tidy/src/deps.rs6
-rw-r--r--tests/ui/auto-traits/issue-83857-ub.rs2
-rw-r--r--tests/ui/auto-traits/issue-83857-ub.stderr4
-rw-r--r--tests/ui/impl-trait/auto-trait-leak0
-rw-r--r--tests/ui/lexer/lex-emoji-identifiers.rs6
-rw-r--r--tests/ui/lexer/lex-emoji-identifiers.stderr34
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr13
-rw-r--r--tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs14
24 files changed, 228 insertions, 134 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 53e1e4d7567..9f6df6e14c6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3786,7 +3786,7 @@ name = "rustc_lexer"
 version = "0.1.0"
 dependencies = [
  "expect-test",
- "unic-emoji-char",
+ "unicode-properties",
  "unicode-xid",
 ]
 
@@ -5447,38 +5447,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "unic-char-property"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
-dependencies = [
- "unic-char-range",
-]
-
-[[package]]
-name = "unic-char-range"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
-
-[[package]]
-name = "unic-common"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
-
-[[package]]
-name = "unic-emoji-char"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b07221e68897210270a38bde4babb655869637af0f69407f96053a34f76494d"
-dependencies = [
- "unic-char-property",
- "unic-char-range",
- "unic-ucd-version",
-]
-
-[[package]]
 name = "unic-langid"
 version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5522,15 +5490,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "unic-ucd-version"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
-dependencies = [
- "unic-common",
-]
-
-[[package]]
 name = "unicase"
 version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5568,6 +5527,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "unicode-properties"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7f91c8b21fbbaa18853c3d0801c78f4fc94cdb976699bb03e832e75f7fd22f0"
+
+[[package]]
 name = "unicode-script"
 version = "0.5.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml
index 23294dc2e1b..2211ac1c8a7 100644
--- a/compiler/rustc_lexer/Cargo.toml
+++ b/compiler/rustc_lexer/Cargo.toml
@@ -16,7 +16,11 @@ Rust lexer used by rustc. No stability guarantees are provided.
 # Note that this crate purposefully does not depend on other rustc crates
 [dependencies]
 unicode-xid = "0.2.0"
-unic-emoji-char = "0.9.0"
+
+[dependencies.unicode-properties]
+version = "0.1.0"
+default-features = false
+features = ["emoji"]
 
 [dev-dependencies]
 expect-test = "1.4.0"
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index d511d2b1280..43dfd34a6ff 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -34,6 +34,7 @@ pub use crate::cursor::Cursor;
 use self::LiteralKind::*;
 use self::TokenKind::*;
 use crate::cursor::EOF_CHAR;
+use unicode_properties::UnicodeEmoji;
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -428,9 +429,7 @@ impl Cursor<'_> {
                 Literal { kind, suffix_start }
             }
             // Identifier starting with an emoji. Only lexed for graceful error recovery.
-            c if !c.is_ascii() && unic_emoji_char::is_emoji(c) => {
-                self.fake_ident_or_unknown_prefix()
-            }
+            c if !c.is_ascii() && c.is_emoji_char() => self.fake_ident_or_unknown_prefix(),
             _ => Unknown,
         };
         let res = Token::new(token_kind, self.pos_within_token());
@@ -514,9 +513,7 @@ impl Cursor<'_> {
         // we see a prefix here, it is definitely an unknown prefix.
         match self.first() {
             '#' | '"' | '\'' => UnknownPrefix,
-            c if !c.is_ascii() && unic_emoji_char::is_emoji(c) => {
-                self.fake_ident_or_unknown_prefix()
-            }
+            c if !c.is_ascii() && c.is_emoji_char() => self.fake_ident_or_unknown_prefix(),
             _ => Ident,
         }
     }
@@ -525,7 +522,7 @@ impl Cursor<'_> {
         // Start is already eaten, eat the rest of identifier.
         self.eat_while(|c| {
             unicode_xid::UnicodeXID::is_xid_continue(c)
-                || (!c.is_ascii() && unic_emoji_char::is_emoji(c))
+                || (!c.is_ascii() && c.is_emoji_char())
                 || c == '\u{200d}'
         });
         // Known prefixes must have been handled earlier. So if
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 16744db7e4c..365ef368248 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -132,7 +132,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
         use mir::Rvalue::*;
         match self {
             Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
-            Repeat(_, _) => todo!(),
+            Repeat(op, len) => stable_mir::mir::Rvalue::Repeat(op.stable(tables), opaque(len)),
             Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
                 opaque(region),
                 kind.stable(tables),
@@ -145,7 +145,11 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
             }
             Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
-            Cast(_, _, _) => todo!(),
+            Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
+                cast_kind.stable(tables),
+                op.stable(tables),
+                tables.intern_ty(*ty),
+            ),
             BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
                 bin_op.stable(tables),
                 ops.0.stable(tables),
@@ -163,8 +167,13 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
             }
             Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
-            Aggregate(_, _) => todo!(),
-            ShallowInitBox(_, _) => todo!(),
+            Aggregate(agg_kind, operands) => {
+                let operands = operands.iter().map(|op| op.stable(tables)).collect();
+                stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
+            }
+            ShallowInitBox(op, ty) => {
+                stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), tables.intern_ty(*ty))
+            }
             CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
         }
     }
@@ -478,6 +487,40 @@ impl<'tcx> Stable<'tcx> for mir::UnOp {
     }
 }
 
+impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
+    type T = stable_mir::mir::AggregateKind;
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        match self {
+            mir::AggregateKind::Array(ty) => {
+                stable_mir::mir::AggregateKind::Array(tables.intern_ty(*ty))
+            }
+            mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
+            mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
+                stable_mir::mir::AggregateKind::Adt(
+                    rustc_internal::adt_def(*def_id),
+                    var_idx.index(),
+                    generic_arg.stable(tables),
+                    user_ty_index.map(|idx| idx.index()),
+                    field_idx.map(|idx| idx.index()),
+                )
+            }
+            mir::AggregateKind::Closure(def_id, generic_arg) => {
+                stable_mir::mir::AggregateKind::Closure(
+                    rustc_internal::closure_def(*def_id),
+                    generic_arg.stable(tables),
+                )
+            }
+            mir::AggregateKind::Generator(def_id, generic_arg, movability) => {
+                stable_mir::mir::AggregateKind::Generator(
+                    rustc_internal::generator_def(*def_id),
+                    generic_arg.stable(tables),
+                    movability.stable(tables),
+                )
+            }
+        }
+    }
+}
+
 impl<'tcx> Stable<'tcx> for rustc_hir::GeneratorKind {
     type T = stable_mir::mir::GeneratorKind;
     fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index 1b1871bcd2a..e08359067df 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,4 +1,6 @@
-use crate::stable_mir::ty::Region;
+use crate::stable_mir::ty::{
+    AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
+};
 use crate::stable_mir::{self, ty::Ty};
 
 #[derive(Clone, Debug)]
@@ -137,7 +139,6 @@ pub enum Statement {
     Nop,
 }
 
-// FIXME this is incomplete
 #[derive(Clone, Debug)]
 pub enum Rvalue {
     /// Creates a pointer with the indicated mutability to the place.
@@ -146,6 +147,16 @@ pub enum Rvalue {
     /// `&raw v` or `addr_of!(v)`.
     AddressOf(Mutability, Place),
 
+    /// Creates an aggregate value, like a tuple or struct.
+    ///
+    /// This is needed because dataflow analysis needs to distinguish
+    /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
+    /// has a destructor.
+    ///
+    /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
+    /// generator lowering, `Generator` aggregate kinds are disallowed too.
+    Aggregate(AggregateKind, Vec<Operand>),
+
     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
@@ -198,6 +209,16 @@ pub enum Rvalue {
     /// Creates a reference to the place.
     Ref(Region, BorrowKind, Place),
 
+    /// Creates an array where each element is the value of the operand.
+    ///
+    /// This is the cause of a bug in the case where the repetition count is zero because the value
+    /// is not dropped, see [#74836].
+    ///
+    /// Corresponds to source code like `[x; 32]`.
+    ///
+    /// [#74836]: https://github.com/rust-lang/rust/issues/74836
+    Repeat(Operand, Const),
+
     /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
     ///
     /// This is different from a normal transmute because dataflow analysis will treat the box as
@@ -233,6 +254,15 @@ pub enum Rvalue {
 }
 
 #[derive(Clone, Debug)]
+pub enum AggregateKind {
+    Array(Ty),
+    Tuple,
+    Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
+    Closure(ClosureDef, GenericArgs),
+    Generator(GeneratorDef, GenericArgs, Movability),
+}
+
+#[derive(Clone, Debug)]
 pub enum Operand {
     Copy(Place),
     Move(Place),
@@ -247,6 +277,11 @@ pub struct Place {
 
 type FieldIdx = usize;
 
+/// The source-order index of a variant in a type.
+type VariantIdx = usize;
+
+type UserTypeAnnotationIndex = usize;
+
 #[derive(Clone, Debug)]
 pub struct SwitchTarget {
     pub value: u128,
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 7a72afd666c..025225b8d19 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -10,7 +10,7 @@ impl Ty {
     }
 }
 
-type Const = Opaque;
+pub(crate) type Const = Opaque;
 pub(crate) type Region = Opaque;
 type Span = Opaque;
 
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 409bcf5ce61..1aef9a885bc 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -100,10 +100,18 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
                 rematch_impl(self, goal, def_id, nested_obligations)
             }
 
+            // If an unsize goal is ambiguous, then we can manually rematch it to make
+            // selection progress for coercion during HIR typeck. If it is *not* ambiguous,
+            // but is `BuiltinImplSource::Misc`, it may have nested `Unsize` goals,
+            // and we need to rematch those to detect tuple unsizing and trait upcasting.
+            // FIXME: This will be wrong if we have param-env or where-clause bounds
+            // with the unsize goal -- we may need to mark those with different impl
+            // sources.
             (Certainty::Maybe(_), CandidateSource::BuiltinImpl(src))
+            | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
                 if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
             {
-                rematch_unsize(self, goal, nested_obligations, src)
+                rematch_unsize(self, goal, nested_obligations, src, certainty)
             }
 
             // Technically some builtin impls have nested obligations, but if
@@ -217,6 +225,7 @@ fn rematch_unsize<'tcx>(
     goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
     mut nested: Vec<PredicateObligation<'tcx>>,
     source: BuiltinImplSource,
+    certainty: Certainty,
 ) -> SelectionResult<'tcx, Selection<'tcx>> {
     let tcx = infcx.tcx;
     let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested);
@@ -227,6 +236,12 @@ fn rematch_unsize<'tcx>(
         &mut nested,
     );
     match (a_ty.kind(), b_ty.kind()) {
+        // Stall any ambiguous upcasting goals, since we can't rematch those
+        (ty::Dynamic(_, _, ty::Dyn), ty::Dynamic(_, _, ty::Dyn)) => match certainty {
+            Certainty::Yes => Ok(Some(ImplSource::Builtin(source, nested))),
+            _ => Ok(None),
+        },
+        // `T` -> `dyn Trait` upcasting
         (_, &ty::Dynamic(data, region, ty::Dyn)) => {
             // Check that the type implements all of the predicates of the def-id.
             // (i.e. the principal, all of the associated types match, and any auto traits)
@@ -354,10 +369,10 @@ fn rematch_unsize<'tcx>(
             );
             Ok(Some(ImplSource::Builtin(source, nested)))
         }
-        // FIXME: We *could* ICE here if either:
-        // 1. the certainty is `Certainty::Yes`,
-        // 2. we're in codegen (which should mean `Certainty::Yes`).
-        _ => Ok(None),
+        _ => {
+            assert_ne!(certainty, Certainty::Yes);
+            Ok(None)
+        }
     }
 }
 
diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs
index 5f06a7b0795..2e8534f651a 100644
--- a/library/core/src/cell/once.rs
+++ b/library/core/src/cell/once.rs
@@ -250,10 +250,12 @@ impl<T> Default for OnceCell<T> {
 #[stable(feature = "once_cell", since = "1.70.0")]
 impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut d = f.debug_tuple("OnceCell");
         match self.get() {
-            Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
-            None => f.write_str("OnceCell(Uninit)"),
-        }
+            Some(v) => d.field(v),
+            None => d.field(&format_args!("<uninit>")),
+        };
+        d.finish()
     }
 }
 
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 1786b309c5b..9ce6093f1d1 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2521,22 +2521,12 @@ impl<T: Copy + Debug> Debug for Cell<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Debug> Debug for RefCell<T> {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        let mut d = f.debug_struct("RefCell");
         match self.try_borrow() {
-            Ok(borrow) => f.debug_struct("RefCell").field("value", &borrow).finish(),
-            Err(_) => {
-                // The RefCell is mutably borrowed so we can't look at its value
-                // here. Show a placeholder instead.
-                struct BorrowedPlaceholder;
-
-                impl Debug for BorrowedPlaceholder {
-                    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-                        f.write_str("<borrowed>")
-                    }
-                }
-
-                f.debug_struct("RefCell").field("value", &BorrowedPlaceholder).finish()
-            }
-        }
+            Ok(borrow) => d.field("value", &borrow),
+            Err(_) => d.field("value", &format_args!("<borrowed>")),
+        };
+        d.finish()
     }
 }
 
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 3ddb8748753..b0484474712 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -156,6 +156,8 @@
 
 #[stable(feature = "alloc_c_string", since = "1.64.0")]
 pub use alloc::ffi::{CString, FromVecWithNulError, IntoStringError, NulError};
+#[stable(feature = "cstr_from_bytes_until_nul", since = "CURRENT_RUSTC_VERSION")]
+pub use core::ffi::FromBytesUntilNulError;
 #[stable(feature = "core_c_str", since = "1.64.0")]
 pub use core::ffi::{CStr, FromBytesWithNulError};
 
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index 1aeed406562..3598598cfa0 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -222,10 +222,12 @@ impl<T: Default> Default for LazyLock<T> {
 #[unstable(feature = "lazy_cell", issue = "109736")]
 impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut d = f.debug_tuple("LazyLock");
         match self.get() {
-            Some(v) => f.debug_tuple("LazyLock").field(v).finish(),
-            None => f.write_str("LazyLock(Uninit)"),
-        }
+            Some(v) => d.field(v),
+            None => d.field(&format_args!("<uninit>")),
+        };
+        d.finish()
     }
 }
 
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index b8fec6902a0..b4ae6b7e07e 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -490,13 +490,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
                 d.field("data", &&**err.get_ref());
             }
             Err(TryLockError::WouldBlock) => {
-                struct LockedPlaceholder;
-                impl fmt::Debug for LockedPlaceholder {
-                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                        f.write_str("<locked>")
-                    }
-                }
-                d.field("data", &LockedPlaceholder);
+                d.field("data", &format_args!("<locked>"));
             }
         }
         d.field("poisoned", &self.poison.get());
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index e83bc35ee98..e2b7b893cb5 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -365,10 +365,12 @@ impl<T> Default for OnceLock<T> {
 #[stable(feature = "once_cell", since = "1.70.0")]
 impl<T: fmt::Debug> fmt::Debug for OnceLock<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut d = f.debug_tuple("OnceLock");
         match self.get() {
-            Some(v) => f.debug_tuple("Once").field(v).finish(),
-            None => f.write_str("Once(Uninit)"),
-        }
+            Some(v) => d.field(v),
+            None => d.field(&format_args!("<uninit>")),
+        };
+        d.finish()
     }
 }
 
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 7c409cb3e97..26aaa2414c9 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -485,13 +485,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
                 d.field("data", &&**err.get_ref());
             }
             Err(TryLockError::WouldBlock) => {
-                struct LockedPlaceholder;
-                impl fmt::Debug for LockedPlaceholder {
-                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                        f.write_str("<locked>")
-                    }
-                }
-                d.field("data", &LockedPlaceholder);
+                d.field("data", &format_args!("<locked>"));
             }
         }
         d.field("poisoned", &self.poison.get());
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 6b35b13e586..c85418baecd 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -1,8 +1,8 @@
 use crate::environment::Environment;
 use crate::exec::cmd;
-use crate::utils::io::{copy_directory, unpack_archive};
+use crate::utils::io::{copy_directory, find_file_in_dir, unpack_archive};
 use anyhow::Context;
-use camino::Utf8PathBuf;
+use camino::{Utf8Path, Utf8PathBuf};
 
 /// Run tests on optimized dist artifacts.
 pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
@@ -22,13 +22,14 @@ pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> {
         Ok(extracted_path)
     };
     let host_triple = env.host_triple();
+    let version = find_dist_version(&dist_dir)?;
 
     // Extract rustc, libstd, cargo and src archives to create the optimized sysroot
-    let rustc_dir = extract_dist_dir(&format!("rustc-nightly-{host_triple}"))?.join("rustc");
-    let libstd_dir = extract_dist_dir(&format!("rust-std-nightly-{host_triple}"))?
+    let rustc_dir = extract_dist_dir(&format!("rustc-{version}-{host_triple}"))?.join("rustc");
+    let libstd_dir = extract_dist_dir(&format!("rust-std-{version}-{host_triple}"))?
         .join(format!("rust-std-{host_triple}"));
-    let cargo_dir = extract_dist_dir(&format!("cargo-nightly-{host_triple}"))?.join("cargo");
-    let extracted_src_dir = extract_dist_dir("rust-src-nightly")?.join("rust-src");
+    let cargo_dir = extract_dist_dir(&format!("cargo-{version}-{host_triple}"))?.join("cargo");
+    let extracted_src_dir = extract_dist_dir(&format!("rust-src-{version}"))?.join("rust-src");
 
     // We need to manually copy libstd to the extracted rustc sysroot
     copy_directory(
@@ -99,3 +100,15 @@ llvm-config = "{llvm_config}"
     }
     cmd(&args).env("COMPILETEST_FORCE_STAGE0", "1").run().context("Cannot execute tests")
 }
+
+/// Tries to find the version of the dist artifacts (either nightly, beta, or 1.XY.Z).
+fn find_dist_version(directory: &Utf8Path) -> anyhow::Result<String> {
+    // Lookup a known file with a unique prefix and extract the version from its filename
+    let archive = find_file_in_dir(directory, "reproducible-artifacts-", ".tar.xz")?
+        .file_name()
+        .unwrap()
+        .to_string();
+    let (version, _) =
+        archive.strip_prefix("reproducible-artifacts-").unwrap().split_once("-").unwrap();
+    Ok(version.to_string())
+}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 57cbfe68be4..a015c36d7eb 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -270,18 +270,14 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "twox-hash",
     "type-map",
     "typenum",
-    "unic-char-property",
-    "unic-char-range",
-    "unic-common",
-    "unic-emoji-char",
     "unic-langid",
     "unic-langid-impl",
     "unic-langid-macros",
     "unic-langid-macros-impl",
-    "unic-ucd-version",
     "unicase",
     "unicode-ident",
     "unicode-normalization",
+    "unicode-properties",
     "unicode-script",
     "unicode-security",
     "unicode-width",
diff --git a/tests/ui/auto-traits/issue-83857-ub.rs b/tests/ui/auto-traits/issue-83857-ub.rs
index 0a8865295c6..626e60c37f6 100644
--- a/tests/ui/auto-traits/issue-83857-ub.rs
+++ b/tests/ui/auto-traits/issue-83857-ub.rs
@@ -1,4 +1,6 @@
 #![allow(suspicious_auto_trait_impls)]
+// Tests that we don't incorrectly allow overlap between a builtin auto trait
+// impl and a user written one. See #83857 for more details
 
 struct Always<T, U>(T, U);
 unsafe impl<T, U> Send for Always<T, U> {}
diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr
index d2aef17e7f8..23a2f62d905 100644
--- a/tests/ui/auto-traits/issue-83857-ub.stderr
+++ b/tests/ui/auto-traits/issue-83857-ub.stderr
@@ -1,12 +1,12 @@
 error[E0277]: `Foo<T, U>` cannot be sent between threads safely
-  --> $DIR/issue-83857-ub.rs:20:38
+  --> $DIR/issue-83857-ub.rs:22:38
    |
 LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `Foo<T, U>`
 note: required for `Foo<T, U>` to implement `WithAssoc`
-  --> $DIR/issue-83857-ub.rs:13:15
+  --> $DIR/issue-83857-ub.rs:15:15
    |
 LL | impl<T: Send> WithAssoc for T {
    |         ----  ^^^^^^^^^     ^
diff --git a/tests/ui/impl-trait/auto-trait-leak b/tests/ui/impl-trait/auto-trait-leak
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/tests/ui/impl-trait/auto-trait-leak
+++ /dev/null
diff --git a/tests/ui/lexer/lex-emoji-identifiers.rs b/tests/ui/lexer/lex-emoji-identifiers.rs
index 91b5929c0fe..decf2f00587 100644
--- a/tests/ui/lexer/lex-emoji-identifiers.rs
+++ b/tests/ui/lexer/lex-emoji-identifiers.rs
@@ -1,9 +1,7 @@
 fn invalid_emoji_usages() {
     let arrow↔️ = "basic emoji"; //~ ERROR: identifiers cannot contain emoji
-    // FIXME
-    let planet🪐 = "basic emoji"; //~ ERROR: unknown start of token
-    // FIXME
-    let wireless🛜 = "basic emoji"; //~ ERROR: unknown start of token
+    let planet🪐 = "basic emoji"; //~ ERROR: identifiers cannot contain emoji
+    let wireless🛜 = "basic emoji"; //~ ERROR: identifiers cannot contain emoji
     // FIXME
     let key1️⃣ = "keycap sequence"; //~ ERROR: unknown start of token
                                     //~^ WARN: identifier contains uncommon Unicode codepoints
diff --git a/tests/ui/lexer/lex-emoji-identifiers.stderr b/tests/ui/lexer/lex-emoji-identifiers.stderr
index 6237c5d0236..747825fa2a9 100644
--- a/tests/ui/lexer/lex-emoji-identifiers.stderr
+++ b/tests/ui/lexer/lex-emoji-identifiers.stderr
@@ -1,17 +1,5 @@
-error: unknown start of token: \u{1fa90}
-  --> $DIR/lex-emoji-identifiers.rs:4:15
-   |
-LL |     let planet🪐 = "basic emoji";
-   |               ^^
-
-error: unknown start of token: \u{1f6dc}
-  --> $DIR/lex-emoji-identifiers.rs:6:17
-   |
-LL |     let wireless🛜 = "basic emoji";
-   |                 ^^
-
 error: unknown start of token: \u{20e3}
-  --> $DIR/lex-emoji-identifiers.rs:8:14
+  --> $DIR/lex-emoji-identifiers.rs:6:14
    |
 LL |     let key1️⃣ = "keycap sequence";
    |             ^
@@ -22,26 +10,38 @@ error: identifiers cannot contain emoji: `arrow↔️`
 LL |     let arrow↔️ = "basic emoji";
    |         ^^^^^^
 
+error: identifiers cannot contain emoji: `planet🪐`
+  --> $DIR/lex-emoji-identifiers.rs:3:9
+   |
+LL |     let planet🪐 = "basic emoji";
+   |         ^^^^^^^^
+
+error: identifiers cannot contain emoji: `wireless🛜`
+  --> $DIR/lex-emoji-identifiers.rs:4:9
+   |
+LL |     let wireless🛜 = "basic emoji";
+   |         ^^^^^^^^^^
+
 error: identifiers cannot contain emoji: `flag🇺🇳`
-  --> $DIR/lex-emoji-identifiers.rs:10:9
+  --> $DIR/lex-emoji-identifiers.rs:8:9
    |
 LL |     let flag🇺🇳 = "flag sequence";
    |         ^^^^^^
 
 error: identifiers cannot contain emoji: `wales🏴`
-  --> $DIR/lex-emoji-identifiers.rs:11:9
+  --> $DIR/lex-emoji-identifiers.rs:9:9
    |
 LL |     let wales🏴 = "tag sequence";
    |         ^^^^^^^
 
 error: identifiers cannot contain emoji: `folded🙏🏿`
-  --> $DIR/lex-emoji-identifiers.rs:12:9
+  --> $DIR/lex-emoji-identifiers.rs:10:9
    |
 LL |     let folded🙏🏿 = "modifier sequence";
    |         ^^^^^^^^^^
 
 warning: identifier contains uncommon Unicode codepoints
-  --> $DIR/lex-emoji-identifiers.rs:8:9
+  --> $DIR/lex-emoji-identifiers.rs:6:9
    |
 LL |     let key1️⃣ = "keycap sequence";
    |         ^^^^
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr
new file mode 100644
index 00000000000..9f0993d65a7
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.current.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+  --> $DIR/upcast-through-struct-tail.rs:10:5
+   |
+LL |     x
+   |     ^
+   |
+   = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+   = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+   = note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr
new file mode 100644
index 00000000000..9f0993d65a7
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.next.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+  --> $DIR/upcast-through-struct-tail.rs:10:5
+   |
+LL |     x
+   |     ^
+   |
+   = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+   = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+   = note: required when coercing `Box<Wrapper<(dyn A + 'a)>>` into `Box<Wrapper<(dyn B + 'a)>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
new file mode 100644
index 00000000000..42495f45f8a
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/upcast-through-struct-tail.rs
@@ -0,0 +1,14 @@
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+struct Wrapper<T: ?Sized>(T);
+
+trait A: B {}
+trait B {}
+
+fn test<'a>(x: Box<Wrapper<dyn A + 'a>>) -> Box<Wrapper<dyn B + 'a>> {
+    x
+    //~^ ERROR cannot cast `dyn A` to `dyn B`, trait upcasting coercion is experimental
+}
+
+fn main() {}