about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-26 22:49:52 +0000
committerbors <bors@rust-lang.org>2024-09-26 22:49:52 +0000
commit58420a065b68ecb3eec03b942740c761cdadd5c4 (patch)
treeb4f48e9b7b076a79ba16303f68a63f12f53d81fa
parent2bd1e894efde3b6be857ad345914a3b1cea51def (diff)
parent3d4d45f87b8707ea7a98827f64fad4ab30f0c2ba (diff)
downloadrust-58420a065b68ecb3eec03b942740c761cdadd5c4.tar.gz
rust-58420a065b68ecb3eec03b942740c761cdadd5c4.zip
Auto merge of #130907 - GuillaumeGomez:rollup-423r4i4, r=GuillaumeGomez
Rollup of 11 pull requests

Successful merges:

 - #130279 (Document subtleties of `ManuallyDrop`)
 - #130517 (Add the library workspace to the suggested rust-analyzer config)
 - #130820 (Fix diagnostics for coroutines with () as input.)
 - #130833 (Fix the misleading diagnostic for `let_underscore_drop` on type without `Drop` implementation)
 - #130845 (Utf8Chunks: add link to Utf8Chunk)
 - #130850 (Pass Module Analysis Manager to Standard Instrumentations)
 - #130861 (Use `mem::offset_of!` for `sockaddr_un.sun_path`)
 - #130862 (rustdoc: do not animate :target when user prefers reduced motion)
 - #130868 (Update FIXME comment in s390x_unknown_linux_*.rs)
 - #130879 (Pass correct HirId to late_bound_vars in diagnostic code)
 - #130880 (add missing FIXME(const-hack))

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs3
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp11
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs5
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs72
-rw-r--r--library/core/src/mem/manually_drop.rs130
-rw-r--r--library/core/src/ptr/alignment.rs2
-rw-r--r--library/core/src/str/lossy.rs4
-rw-r--r--library/std/src/os/unix/net/addr.rs21
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs1
-rw-r--r--src/etc/rust_analyzer_settings.json1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css19
-rw-r--r--tests/crashes/125655.rs8
-rw-r--r--tests/ui/closures/binder/closure-return-type-mismatch.rs15
-rw-r--r--tests/ui/closures/binder/closure-return-type-mismatch.stderr25
-rw-r--r--tests/ui/closures/closure-return-type-mismatch.rs4
-rw-r--r--tests/ui/closures/closure-return-type-mismatch.stderr10
-rw-r--r--tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs11
-rw-r--r--tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr15
-rw-r--r--tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs2
-rw-r--r--tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr2
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.rs4
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.stderr4
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_drop.rs2
-rw-r--r--tests/ui/lint/let_underscore/let_underscore_drop.stderr2
27 files changed, 282 insertions, 100 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 5f89f7dedc2..487cc7e55cd 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -882,7 +882,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let ty = self.lowerer().lower_ty(hir_ty);
                     debug!(?ty, "return type (lowered)");
                     debug!(?expected, "expected type");
-                    let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
+                    let bound_vars =
+                        self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
                     let ty = Binder::bind_with_vars(ty, bound_vars);
                     let ty = self.normalize(hir_ty.span, ty);
                     let ty = self.tcx.instantiate_bound_regions_with_erased(ty);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 375cfccbe9f..a286ccb22c7 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -531,7 +531,7 @@ lint_non_binding_let_multi_suggestion =
     consider immediately dropping the value
 
 lint_non_binding_let_on_drop_type =
-    non-binding let on a type that implements `Drop`
+    non-binding let on a type that has a destructor
 
 lint_non_binding_let_on_sync_lock = non-binding let on a synchronization lock
     .label = this lock is not assigned to a binding and is immediately dropped
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
index a12a97ee573..abee9ee7869 100644
--- a/compiler/rustc_lint/src/let_underscore.rs
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -51,7 +51,7 @@ declare_lint! {
     /// intent.
     pub LET_UNDERSCORE_DROP,
     Allow,
-    "non-binding let on a type that implements `Drop`"
+    "non-binding let on a type that has a destructor"
 }
 
 declare_lint! {
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 165fb7aa6c3..8f0b1b81276 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -732,12 +732,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   PTO.SLPVectorization = SLPVectorize;
   PTO.MergeFunctions = MergeFunctions;
 
-  // FIXME: We may want to expose this as an option.
-  bool DebugPassManager = false;
-
   PassInstrumentationCallbacks PIC;
-  StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
-  SI.registerCallbacks(PIC);
 
   if (LlvmSelfProfiler) {
     LLVMSelfProfileInitializeCallbacks(PIC, LlvmSelfProfiler,
@@ -784,6 +779,12 @@ extern "C" LLVMRustResult LLVMRustOptimize(
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
+  // FIXME: We may want to expose this as an option.
+  bool DebugPassManager = false;
+
+  StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
+  SI.registerCallbacks(PIC, &MAM);
+
   if (LLVMPluginsLen) {
     auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
     SmallVector<StringRef> Plugins;
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index a8163e228e6..3efbb464836 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -6,9 +6,8 @@ pub(crate) fn target() -> Target {
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
-    // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
-    // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
-    // also strip v128 from the data_layout below to match the older LLVM's expectation.
+    // FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
+    // ABI. Pass the -vector feature string to LLVM to respect this assumption.
     base.features = "-vector".into();
     base.max_atomic_width = Some(128);
     base.min_global_align = Some(16);
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index e52bcc987f9..65b5c1167bd 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -6,9 +6,8 @@ pub(crate) fn target() -> Target {
     base.endian = Endian::Big;
     // z10 is the oldest CPU supported by LLVM
     base.cpu = "z10".into();
-    // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
-    // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
-    // also strip v128 from the data_layout below to match the older LLVM's expectation.
+    // FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
+    // ABI. Pass the -vector feature string to LLVM to respect this assumption.
     base.features = "-vector".into();
     base.max_atomic_width = Some(128);
     base.min_global_align = Some(16);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 19e2679ae4d..969f2528836 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -2635,49 +2635,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // This shouldn't be common unless manually implementing one of the
         // traits manually, but don't make it more confusing when it does
         // happen.
-        Ok(
-            if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait()
-                && not_tupled
-            {
-                self.report_and_explain_type_error(
-                    TypeTrace::trait_refs(
-                        &obligation.cause,
-                        true,
-                        expected_trait_ref,
-                        found_trait_ref,
-                    ),
-                    ty::error::TypeError::Mismatch,
-                )
-            } else if found.len() == expected.len() {
-                self.report_closure_arg_mismatch(
-                    span,
-                    found_span,
-                    found_trait_ref,
-                    expected_trait_ref,
-                    obligation.cause.code(),
-                    found_node,
-                    obligation.param_env,
-                )
-            } else {
-                let (closure_span, closure_arg_span, found) = found_did
-                    .and_then(|did| {
-                        let node = self.tcx.hir().get_if_local(did)?;
-                        let (found_span, closure_arg_span, found) =
-                            self.get_fn_like_arguments(node)?;
-                        Some((Some(found_span), closure_arg_span, found))
-                    })
-                    .unwrap_or((found_span, None, found));
-
-                self.report_arg_count_mismatch(
+        if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled
+        {
+            return Ok(self.report_and_explain_type_error(
+                TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref),
+                ty::error::TypeError::Mismatch,
+            ));
+        }
+        if found.len() != expected.len() {
+            let (closure_span, closure_arg_span, found) = found_did
+                .and_then(|did| {
+                    let node = self.tcx.hir().get_if_local(did)?;
+                    let (found_span, closure_arg_span, found) = self.get_fn_like_arguments(node)?;
+                    Some((Some(found_span), closure_arg_span, found))
+                })
+                .unwrap_or((found_span, None, found));
+
+            // If the coroutine take a single () as its argument,
+            // the trait argument would found the coroutine take 0 arguments,
+            // but get_fn_like_arguments would give 1 argument.
+            // This would result in "Expected to take 1 argument, but it takes 1 argument".
+            // Check again to avoid this.
+            if found.len() != expected.len() {
+                return Ok(self.report_arg_count_mismatch(
                     span,
                     closure_span,
                     expected,
                     found,
                     found_trait_ty.is_closure(),
                     closure_arg_span,
-                )
-            },
-        )
+                ));
+            }
+        }
+        Ok(self.report_closure_arg_mismatch(
+            span,
+            found_span,
+            found_trait_ref,
+            expected_trait_ref,
+            obligation.cause.code(),
+            found_node,
+            obligation.param_env,
+        ))
     }
 
     /// Given some node representing a fn-like thing in the HIR map,
diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs
index 3e47785ee48..7d519384e37 100644
--- a/library/core/src/mem/manually_drop.rs
+++ b/library/core/src/mem/manually_drop.rs
@@ -1,22 +1,21 @@
 use crate::ops::{Deref, DerefMut, DerefPure};
 use crate::ptr;
 
-/// A wrapper to inhibit the compiler from automatically calling `T`’s destructor.
-/// This wrapper is 0-cost.
+/// A wrapper to inhibit the compiler from automatically calling `T`’s
+/// destructor. This wrapper is 0-cost.
 ///
 /// `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
-/// `T`, and is subject to the same layout optimizations as `T`. As a consequence,
-/// it has *no effect* on the assumptions that the compiler makes about its
-/// contents. For example, initializing a `ManuallyDrop<&mut T>` with [`mem::zeroed`]
-/// is undefined behavior. If you need to handle uninitialized data, use
-/// [`MaybeUninit<T>`] instead.
+/// `T`, and is subject to the same layout optimizations as `T`. As a
+/// consequence, it has *no effect* on the assumptions that the compiler makes
+/// about its contents. For example, initializing a `ManuallyDrop<&mut T>` with
+/// [`mem::zeroed`] is undefined behavior. If you need to handle uninitialized
+/// data, use [`MaybeUninit<T>`] instead.
 ///
-/// Note that accessing the value inside a `ManuallyDrop<T>` is safe.
-/// This means that a `ManuallyDrop<T>` whose content has been dropped must not
-/// be exposed through a public safe API.
-/// Correspondingly, `ManuallyDrop::drop` is unsafe.
+/// Note that accessing the value inside a `ManuallyDrop<T>` is safe. This means
+/// that a `ManuallyDrop<T>` whose content has been dropped must not be exposed
+/// through a public safe API. Correspondingly, `ManuallyDrop::drop` is unsafe.
 ///
-/// # `ManuallyDrop` and drop order.
+/// # `ManuallyDrop` and drop order
 ///
 /// Rust has a well-defined [drop order] of values. To make sure that fields or
 /// locals are dropped in a specific order, reorder the declarations such that
@@ -40,9 +39,116 @@ use crate::ptr;
 /// }
 /// ```
 ///
+/// # Interaction with `Box`
+///
+/// Currently, if you have a `ManuallyDrop<T>`, where the type `T` is a `Box` or
+/// contains a `Box` inside, then dropping the `T` followed by moving the
+/// `ManuallyDrop<T>` is [considered to be undefined
+/// behavior](https://github.com/rust-lang/unsafe-code-guidelines/issues/245).
+/// That is, the following code causes undefined behavior:
+///
+/// ```no_run
+/// use std::mem::ManuallyDrop;
+///
+/// let mut x = ManuallyDrop::new(Box::new(42));
+/// unsafe {
+///     ManuallyDrop::drop(&mut x);
+/// }
+/// let y = x; // Undefined behavior!
+/// ```
+///
+/// This is [likely to change in the
+/// future](https://rust-lang.github.io/rfcs/3336-maybe-dangling.html). In the
+/// meantime, consider using [`MaybeUninit`] instead.
+///
+/// # Safety hazards when storing `ManuallyDrop` in a struct or an enum.
+///
+/// Special care is needed when all of the conditions below are met:
+/// * A struct or enum contains a `ManuallyDrop`.
+/// * The `ManuallyDrop` is not inside a `union`.
+/// * The struct or enum is part of public API, or is stored in a struct or an
+///   enum that is part of public API.
+/// * There is code that drops the contents of the `ManuallyDrop` field, and
+///   this code is outside the struct or enum's `Drop` implementation.
+///
+/// In particular, the following hazards may occur:
+///
+/// #### Storing generic types
+///
+/// If the `ManuallyDrop` contains a client-supplied generic type, the client
+/// might provide a `Box` as that type. This would cause undefined behavior when
+/// the struct or enum is later moved, as mentioned in the previous section. For
+/// example, the following code causes undefined behavior:
+///
+/// ```no_run
+/// use std::mem::ManuallyDrop;
+///
+/// pub struct BadOption<T> {
+///     // Invariant: Has been dropped iff `is_some` is false.
+///     value: ManuallyDrop<T>,
+///     is_some: bool,
+/// }
+/// impl<T> BadOption<T> {
+///     pub fn new(value: T) -> Self {
+///         Self { value: ManuallyDrop::new(value), is_some: true }
+///     }
+///     pub fn change_to_none(&mut self) {
+///         if self.is_some {
+///             self.is_some = false;
+///             unsafe {
+///                 // SAFETY: `value` hasn't been dropped yet, as per the invariant
+///                 // (This is actually unsound!)
+///                 ManuallyDrop::drop(&mut self.value);
+///             }
+///         }
+///     }
+/// }
+///
+/// // In another crate:
+///
+/// let mut option = BadOption::new(Box::new(42));
+/// option.change_to_none();
+/// let option2 = option; // Undefined behavior!
+/// ```
+///
+/// #### Deriving traits
+///
+/// Deriving `Debug`, `Clone`, `PartialEq`, `PartialOrd`, `Ord`, or `Hash` on
+/// the struct or enum could be unsound, since the derived implementations of
+/// these traits would access the `ManuallyDrop` field. For example, the
+/// following code causes undefined behavior:
+///
+/// ```no_run
+/// use std::mem::ManuallyDrop;
+///
+/// // This derive is unsound in combination with the `ManuallyDrop::drop` call.
+/// #[derive(Debug)]
+/// pub struct Foo {
+///     value: ManuallyDrop<String>,
+/// }
+/// impl Foo {
+///     pub fn new() -> Self {
+///         let mut temp = Self {
+///             value: ManuallyDrop::new(String::from("Unsafe rust is hard."))
+///         };
+///         unsafe {
+///             // SAFETY: `value` hasn't been dropped yet.
+///             ManuallyDrop::drop(&mut temp.value);
+///         }
+///         temp
+///     }
+/// }
+///
+/// // In another crate:
+///
+/// let foo = Foo::new();
+/// println!("{:?}", foo); // Undefined behavior!
+/// ```
+///
 /// [drop order]: https://doc.rust-lang.org/reference/destructors.html
 /// [`mem::zeroed`]: crate::mem::zeroed
 /// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
+/// [`MaybeUninit`]: crate::mem::MaybeUninit
 #[stable(feature = "manually_drop", since = "1.20.0")]
 #[lang = "manually_drop"]
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index ceb5906d226..50706fca5b0 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -155,7 +155,7 @@ impl Alignment {
         !(unsafe { self.as_usize().unchecked_sub(1) })
     }
 
-    // Remove me once `Ord::max` is usable in const
+    // FIXME(const-hack) Remove me once `Ord::max` is usable in const
     pub(crate) const fn max(a: Self, b: Self) -> Self {
         if a.as_usize() > b.as_usize() { a } else { b }
     }
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 3f31107acf0..e7677c8317a 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -8,6 +8,8 @@ impl [u8] {
     /// Creates an iterator over the contiguous valid UTF-8 ranges of this
     /// slice, and the non-UTF-8 fragments in between.
     ///
+    /// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator.
+    ///
     /// # Examples
     ///
     /// This function formats arbitrary but mostly-UTF-8 bytes into Rust source
@@ -148,6 +150,8 @@ impl fmt::Debug for Debug<'_> {
 /// If you want a simple conversion from UTF-8 byte slices to string slices,
 /// [`from_utf8`] is easier to use.
 ///
+/// See the [`Utf8Chunk`] type for documenation of the items yielded by this iterator.
+///
 /// [byteslice]: slice
 /// [`from_utf8`]: super::from_utf8
 ///
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index d7b87d480b7..253e1503cf7 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -15,15 +15,12 @@ mod libc {
     pub type socklen_t = u32;
     pub struct sockaddr;
     #[derive(Clone)]
-    pub struct sockaddr_un;
+    pub struct sockaddr_un {
+        pub sun_path: [u8; 1],
+    }
 }
 
-fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
-    // Work with an actual instance of the type since using a null pointer is UB
-    let base = (addr as *const libc::sockaddr_un).addr();
-    let path = core::ptr::addr_of!(addr.sun_path).addr();
-    path - base
-}
+const SUN_PATH_OFFSET: usize = mem::offset_of!(libc::sockaddr_un, sun_path);
 
 pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
     // SAFETY: All zeros is a valid representation for `sockaddr_un`.
@@ -53,7 +50,7 @@ pub(super) fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::s
         ptr::copy_nonoverlapping(bytes.as_ptr(), addr.sun_path.as_mut_ptr().cast(), bytes.len())
     };
 
-    let mut len = sun_path_offset(&addr) + bytes.len();
+    let mut len = SUN_PATH_OFFSET + bytes.len();
     match bytes.get(0) {
         Some(&0) | None => {}
         Some(_) => len += 1,
@@ -114,13 +111,13 @@ impl SocketAddr {
             let sun_path: &[u8] =
                 unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) };
             len = core::slice::memchr::memchr(0, sun_path)
-                .map_or(len, |new_len| (new_len + sun_path_offset(&addr)) as libc::socklen_t);
+                .map_or(len, |new_len| (new_len + SUN_PATH_OFFSET) as libc::socklen_t);
         }
 
         if len == 0 {
             // When there is a datagram from unnamed unix socket
             // linux returns zero bytes of address
-            len = sun_path_offset(&addr) as libc::socklen_t; // i.e., zero-length address
+            len = SUN_PATH_OFFSET as libc::socklen_t; // i.e., zero-length address
         } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
             return Err(io::const_io_error!(
                 io::ErrorKind::InvalidInput,
@@ -238,7 +235,7 @@ impl SocketAddr {
     }
 
     fn address(&self) -> AddressKind<'_> {
-        let len = self.len as usize - sun_path_offset(&self.addr);
+        let len = self.len as usize - SUN_PATH_OFFSET;
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
         // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
@@ -287,7 +284,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr {
                 addr.sun_path.as_mut_ptr().add(1) as *mut u8,
                 name.len(),
             );
-            let len = (sun_path_offset(&addr) + 1 + name.len()) as libc::socklen_t;
+            let len = (SUN_PATH_OFFSET + 1 + name.len()) as libc::socklen_t;
             SocketAddr::from_parts(addr, len)
         }
     }
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index f4c5fe5ff94..0ee2cb451f3 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -46,6 +46,7 @@ static SETTINGS_HASHES: &[&str] = &[
     "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923",
     "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
     "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
+    "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d",
 ];
 static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyzer_settings.json");
 
diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json
index d329fe997cd..a20105f0ef3 100644
--- a/src/etc/rust_analyzer_settings.json
+++ b/src/etc/rust_analyzer_settings.json
@@ -10,6 +10,7 @@
     ],
     "rust-analyzer.linkedProjects": [
         "Cargo.toml",
+        "library/Cargo.toml",
         "src/tools/x/Cargo.toml",
         "src/bootstrap/Cargo.toml",
         "src/tools/rust-analyzer/Cargo.toml",
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index ae9727a4d4f..40391b1b4df 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1687,7 +1687,6 @@ instead, we check that it's not a "finger" cursor.
 	padding-right: 3px;
 	background-color: var(--target-background-color);
 	border-right: 3px solid var(--target-border-color);
-	animation: 0.65s cubic-bezier(0, 0, 0.1, 1.0) 0.1s targetfadein;
 }
 
 .code-header a.tooltip {
@@ -1712,12 +1711,18 @@ a.tooltip:hover::after {
 	content: "\00a0";
 }
 
-/* This animation is layered onto the mistake-proofing delay for dismissing
-	a hovered tooltip, to ensure it feels responsive even with the delay.
-	*/
-.fade-out {
-	opacity: 0;
-	transition: opacity 0.45s cubic-bezier(0, 0, 0.1, 1.0);
+@media not (prefers-reduced-motion) {
+	:target {
+		animation: 0.65s cubic-bezier(0, 0, 0.1, 1.0) 0.1s targetfadein;
+	}
+
+	/* This animation is layered onto the mistake-proofing delay for dismissing
+		a hovered tooltip, to ensure it feels responsive even with the delay.
+		*/
+	.fade-out {
+		opacity: 0;
+		transition: opacity 0.45s cubic-bezier(0, 0, 0.1, 1.0);
+	}
 }
 
 .popover.tooltip .content {
diff --git a/tests/crashes/125655.rs b/tests/crashes/125655.rs
deleted file mode 100644
index fbf92ca22be..00000000000
--- a/tests/crashes/125655.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: rust-lang/rust#125655
-
-fn main() {
-    static foo: dyn Fn() -> u32 = || -> u32 {
-        ...
-        0
-    };
-}
diff --git a/tests/ui/closures/binder/closure-return-type-mismatch.rs b/tests/ui/closures/binder/closure-return-type-mismatch.rs
new file mode 100644
index 00000000000..398a4c43ee2
--- /dev/null
+++ b/tests/ui/closures/binder/closure-return-type-mismatch.rs
@@ -0,0 +1,15 @@
+// We used to bind the closure return type `&'a ()` with the late-bound vars of
+// the owner (here `main` & `env` resp.) instead of the ones of the enclosing
+// function-like / closure inside diagnostic code which was incorrect.
+
+#![feature(closure_lifetime_binder)]
+
+// issue: rust-lang/rust#130391
+fn main() {
+    let _ = for<'a> |x: &'a u8| -> &'a () { x }; //~ ERROR mismatched types
+}
+
+// issue: rust-lang/rust#130663
+fn env<'r>() {
+    let _ = for<'a> |x: &'a u8| -> &'a () { x }; //~ ERROR mismatched types
+}
diff --git a/tests/ui/closures/binder/closure-return-type-mismatch.stderr b/tests/ui/closures/binder/closure-return-type-mismatch.stderr
new file mode 100644
index 00000000000..67045654f99
--- /dev/null
+++ b/tests/ui/closures/binder/closure-return-type-mismatch.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+  --> $DIR/closure-return-type-mismatch.rs:9:45
+   |
+LL |     let _ = for<'a> |x: &'a u8| -> &'a () { x };
+   |                                    ------   ^ expected `&()`, found `&u8`
+   |                                    |
+   |                                    expected `&'a ()` because of return type
+   |
+   = note: expected reference `&'a ()`
+              found reference `&'a u8`
+
+error[E0308]: mismatched types
+  --> $DIR/closure-return-type-mismatch.rs:14:45
+   |
+LL |     let _ = for<'a> |x: &'a u8| -> &'a () { x };
+   |                                    ------   ^ expected `&()`, found `&u8`
+   |                                    |
+   |                                    expected `&'a ()` because of return type
+   |
+   = note: expected reference `&'a ()`
+              found reference `&'a u8`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/closures/closure-return-type-mismatch.rs b/tests/ui/closures/closure-return-type-mismatch.rs
index 1631bb303e5..e5cda1659de 100644
--- a/tests/ui/closures/closure-return-type-mismatch.rs
+++ b/tests/ui/closures/closure-return-type-mismatch.rs
@@ -15,3 +15,7 @@ fn main() {
         b
     };
 }
+
+// issue: rust-lang/rust#130858 rust-lang/rust#125655
+static FOO: fn() -> bool = || -> bool { 1 };
+//~^ ERROR mismatched types
diff --git a/tests/ui/closures/closure-return-type-mismatch.stderr b/tests/ui/closures/closure-return-type-mismatch.stderr
index 3a2f098d1ef..052bbbb5ed5 100644
--- a/tests/ui/closures/closure-return-type-mismatch.stderr
+++ b/tests/ui/closures/closure-return-type-mismatch.stderr
@@ -1,4 +1,12 @@
 error[E0308]: mismatched types
+  --> $DIR/closure-return-type-mismatch.rs:20:41
+   |
+LL | static FOO: fn() -> bool = || -> bool { 1 };
+   |                                  ----   ^ expected `bool`, found integer
+   |                                  |
+   |                                  expected `bool` because of return type
+
+error[E0308]: mismatched types
   --> $DIR/closure-return-type-mismatch.rs:7:9
    |
 LL |         a
@@ -19,6 +27,6 @@ LL |         if false {
 LL |             return "hello"
    |                    ^^^^^^^ expected `bool`, found `&str`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs
new file mode 100644
index 00000000000..448c7100df6
--- /dev/null
+++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs
@@ -0,0 +1,11 @@
+#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
+
+use std::ops::Coroutine;
+
+fn foo() -> impl Coroutine<u8> {
+    //~^ ERROR type mismatch in coroutine arguments
+    #[coroutine]
+    |_: ()| {}
+}
+
+fn main() { }
diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr
new file mode 100644
index 00000000000..c7d6507fd79
--- /dev/null
+++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr
@@ -0,0 +1,15 @@
+error[E0631]: type mismatch in coroutine arguments
+  --> $DIR/arg-count-mismatch-on-unit-input.rs:5:13
+   |
+LL | fn foo() -> impl Coroutine<u8> {
+   |             ^^^^^^^^^^^^^^^^^^ expected due to this
+...
+LL |     |_: ()| {}
+   |     ------- found signature defined here
+   |
+   = note: expected coroutine signature `fn(u8) -> _`
+              found coroutine signature `fn(()) -> _`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
index b885352dfd9..0973e2f1637 100644
--- a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
+++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
@@ -2,7 +2,7 @@
 
 #![deny(let_underscore_drop)]
 fn main() {
-    let _ = foo(); //~ ERROR non-binding let on a type that implements `Drop`
+    let _ = foo(); //~ ERROR non-binding let on a type that has a destructor
 }
 
 async fn from_config(_: Config) {}
diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
index 86e521580b8..70f9979556a 100644
--- a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
+++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
@@ -1,4 +1,4 @@
-error: non-binding let on a type that implements `Drop`
+error: non-binding let on a type that has a destructor
   --> $DIR/issue-119696-err-on-fn.rs:5:5
    |
 LL |     let _ = foo();
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
index 1dc80a123f6..84abb933911 100644
--- a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
@@ -12,9 +12,9 @@ pub fn ice_cold(beverage: Tait) {
     // Must destructure at least one field of `Foo`
     let Foo { field } = beverage;
     // boom
-    _ = field; //~ ERROR non-binding let on a type that implements `Drop`
+    _ = field; //~ ERROR non-binding let on a type that has a destructor
 
-    let _ = field; //~ ERROR non-binding let on a type that implements `Drop`
+    let _ = field; //~ ERROR non-binding let on a type that has a destructor
 }
 
 
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
index 16df2c720ea..e4b1872bba5 100644
--- a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
@@ -1,4 +1,4 @@
-error: non-binding let on a type that implements `Drop`
+error: non-binding let on a type that has a destructor
   --> $DIR/issue-119697-extra-let.rs:15:5
    |
 LL |     _ = field;
@@ -18,7 +18,7 @@ help: consider immediately dropping the value
 LL |     drop(field);
    |     ~~~~~     +
 
-error: non-binding let on a type that implements `Drop`
+error: non-binding let on a type that has a destructor
   --> $DIR/issue-119697-extra-let.rs:17:5
    |
 LL |     let _ = field;
diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.rs b/tests/ui/lint/let_underscore/let_underscore_drop.rs
index 58988ec05d7..f5a5e4299a1 100644
--- a/tests/ui/lint/let_underscore/let_underscore_drop.rs
+++ b/tests/ui/lint/let_underscore/let_underscore_drop.rs
@@ -10,7 +10,7 @@ impl Drop for NontrivialDrop {
 }
 
 fn main() {
-    let _ = NontrivialDrop; //~WARNING non-binding let on a type that implements `Drop`
+    let _ = NontrivialDrop; //~WARNING non-binding let on a type that has a destructor
 
     let (_, _) = (NontrivialDrop, NontrivialDrop); // This should be ignored.
 }
diff --git a/tests/ui/lint/let_underscore/let_underscore_drop.stderr b/tests/ui/lint/let_underscore/let_underscore_drop.stderr
index 7b7de202e46..09f2587063b 100644
--- a/tests/ui/lint/let_underscore/let_underscore_drop.stderr
+++ b/tests/ui/lint/let_underscore/let_underscore_drop.stderr
@@ -1,4 +1,4 @@
-warning: non-binding let on a type that implements `Drop`
+warning: non-binding let on a type that has a destructor
   --> $DIR/let_underscore_drop.rs:13:5
    |
 LL |     let _ = NontrivialDrop;