about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--compiler/rustc_macros/src/session_diagnostic.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs39
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs33
-rw-r--r--compiler/rustc_passes/src/check_attr.rs65
-rw-r--r--compiler/rustc_passes/src/dead.rs55
-rw-r--r--compiler/rustc_passes/src/lib.rs3
-rw-r--r--compiler/rustc_passes/src/liveness.rs11
-rw-r--r--compiler/rustc_passes/src/reachable.rs32
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs38
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs152
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs9
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs19
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs4
-rw-r--r--library/core/src/sync/atomic.rs94
-rw-r--r--library/portable-simd/crates/core_simd/examples/spectral_norm.rs77
-rw-r--r--library/portable-simd/crates/core_simd/src/comparisons.rs12
-rw-r--r--library/portable-simd/crates/core_simd/src/intrinsics.rs68
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/masks.rs31
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/bitmask.rs23
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/full_masks.rs74
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs57
-rw-r--r--library/portable-simd/crates/core_simd/src/math.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/ops.rs39
-rw-r--r--library/portable-simd/crates/core_simd/src/reduction.rs8
-rw-r--r--library/portable-simd/crates/core_simd/src/round.rs27
-rw-r--r--library/portable-simd/crates/core_simd/src/select.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/to_bytes.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/vector.rs87
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/ptr.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/vendor.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/masks.rs4
-rw-r--r--library/portable-simd/crates/core_simd/tests/ops_macros.rs20
-rw-r--r--library/portable-simd/crates/core_simd/tests/round.rs14
-rw-r--r--library/std/src/sys/windows/net.rs4
-rw-r--r--library/std/src/sys_common/net.rs33
-rw-r--r--src/librustdoc/clean/blanket_impl.rs27
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs53
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs9
-rw-r--r--src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr346
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.rs125
-rw-r--r--src/test/ui/lint/unused/unused_attributes-must_use.stderr175
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.rs1
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr8
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.stderr5
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr5
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr12
-rw-r--r--src/test/ui/symbol-names/basic.legacy.stderr4
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.legacy.stderr74
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.rs68
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.stderr74
-rw-r--r--src/test/ui/symbol-names/const-generics-demangling.v0.stderr74
-rw-r--r--src/test/ui/symbol-names/issue-60925.legacy.stderr4
-rw-r--r--src/test/ui/symbol-names/types.legacy.stderr470
-rw-r--r--src/test/ui/symbol-names/types.rs170
-rw-r--r--src/test/ui/symbol-names/types.verbose-legacy.stderr470
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-2.rs17
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-2.stderr19
-rw-r--r--src/test/ui/typeck/deref-multi.rs26
-rw-r--r--src/test/ui/typeck/deref-multi.stderr72
m---------src/tools/cargo0
65 files changed, 2860 insertions, 607 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8d462a143ab..f0c6e371c38 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -318,7 +318,7 @@ dependencies = [
 
 [[package]]
 name = "cargo"
-version = "0.61.0"
+version = "0.62.0"
 dependencies = [
  "anyhow",
  "atty",
diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs
index 9a7784ca72f..f29683e5e1d 100644
--- a/compiler/rustc_macros/src/session_diagnostic.rs
+++ b/compiler/rustc_macros/src/session_diagnostic.rs
@@ -587,7 +587,6 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
         // next call to `it.next()` retrieves the next character.
         while let Some(c) = it.next() {
             if c == '{' && *it.peek().unwrap_or(&'\0') != '{' {
-                #[must_use]
                 let mut eat_argument = || -> Option<String> {
                     let mut result = String::new();
                     // Format specifiers look like
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 19d8856dc6c..f9435682e53 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -24,6 +24,7 @@ use crate::ty::{
     RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
 };
 use rustc_ast as ast;
+use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::memmap::Mmap;
@@ -58,6 +59,7 @@ use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
 use rustc_target::spec::abi;
 
+use rustc_type_ir::TypeFlags;
 use smallvec::SmallVec;
 use std::any::Any;
 use std::borrow::Borrow;
@@ -140,16 +142,39 @@ impl<'tcx> CtxtInterners<'tcx> {
     /// Interns a type.
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline(never)]
-    fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
+    fn intern_ty(
+        &self,
+        kind: TyKind<'tcx>,
+        sess: &Session,
+        resolutions: &ty::ResolverOutputs,
+    ) -> Ty<'tcx> {
         Ty(Interned::new_unchecked(
             self.type_
                 .intern(kind, |kind| {
                     let flags = super::flags::FlagComputation::for_kind(&kind);
 
+                    // It's impossible to hash inference regions (and will ICE), so we don't need to try to cache them.
+                    // Without incremental, we rarely stable-hash types, so let's not do it proactively.
+                    let stable_hash = if flags.flags.intersects(TypeFlags::HAS_RE_INFER)
+                        || sess.opts.incremental.is_none()
+                    {
+                        Fingerprint::ZERO
+                    } else {
+                        let mut hasher = StableHasher::new();
+                        let mut hcx = StableHashingContext::ignore_spans(
+                            sess,
+                            &resolutions.definitions,
+                            &*resolutions.cstore,
+                        );
+                        kind.hash_stable(&mut hcx, &mut hasher);
+                        hasher.finish()
+                    };
+
                     let ty_struct = TyS {
                         kind,
                         flags: flags.flags,
                         outer_exclusive_binder: flags.outer_exclusive_binder,
+                        stable_hash,
                     };
 
                     InternedInSet(self.arena.alloc(ty_struct))
@@ -887,8 +912,12 @@ pub enum UserType<'tcx> {
 }
 
 impl<'tcx> CommonTypes<'tcx> {
-    fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
-        let mk = |ty| interners.intern_ty(ty);
+    fn new(
+        interners: &CtxtInterners<'tcx>,
+        sess: &Session,
+        resolutions: &ty::ResolverOutputs,
+    ) -> CommonTypes<'tcx> {
+        let mk = |ty| interners.intern_ty(ty, sess, resolutions);
 
         CommonTypes {
             unit: mk(Tuple(List::empty())),
@@ -1162,7 +1191,7 @@ impl<'tcx> TyCtxt<'tcx> {
             s.fatal(&err);
         });
         let interners = CtxtInterners::new(arena);
-        let common_types = CommonTypes::new(&interners);
+        let common_types = CommonTypes::new(&interners, s, &resolutions);
         let common_lifetimes = CommonLifetimes::new(&interners);
         let common_consts = CommonConsts::new(&interners, &common_types);
 
@@ -2276,7 +2305,7 @@ impl<'tcx> TyCtxt<'tcx> {
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline]
     pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
-        self.interners.intern_ty(st)
+        self.interners.intern_ty(st, self.sess, &self.gcx.untracked_resolutions)
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 88c993d98e2..6edcfbcdc6c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -17,6 +17,7 @@ pub use self::Variance::*;
 pub use adt::*;
 pub use assoc::*;
 pub use generics::*;
+use rustc_data_structures::fingerprint::Fingerprint;
 pub use vtable::*;
 
 use crate::metadata::ModChild;
@@ -30,7 +31,7 @@ use rustc_ast as ast;
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::intern::Interned;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::stable_hasher::{HashStable, NodeIdHashingMode, StableHasher};
 use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -424,11 +425,15 @@ crate struct TyS<'tcx> {
     /// De Bruijn indices within the type are contained within `0..D`
     /// (exclusive).
     outer_exclusive_binder: ty::DebruijnIndex,
+
+    /// The stable hash of the type. This way hashing of types will not have to work
+    /// on the address of the type anymore, but can instead just read this field
+    stable_hash: Fingerprint,
 }
 
 // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-static_assert_size!(TyS<'_>, 40);
+static_assert_size!(TyS<'_>, 56);
 
 /// Use this rather than `TyS`, whenever possible.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -442,21 +447,41 @@ static BOOL_TYS: TyS<'static> = TyS {
     kind: ty::Bool,
     flags: TypeFlags::empty(),
     outer_exclusive_binder: DebruijnIndex::from_usize(0),
+    stable_hash: Fingerprint::ZERO,
 };
 
 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Ty<'tcx> {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let TyS {
-            ref kind,
+            kind,
 
             // The other fields just provide fast access to information that is
             // also contained in `kind`, so no need to hash them.
             flags: _,
 
             outer_exclusive_binder: _,
+
+            stable_hash,
         } = self.0.0;
 
-        kind.hash_stable(hcx, hasher);
+        if *stable_hash == Fingerprint::ZERO {
+            // No cached hash available. This can only mean that incremental is disabled.
+            // We don't cache stable hashes in non-incremental mode, because they are used
+            // so rarely that the performance actually suffers.
+
+            let stable_hash: Fingerprint = {
+                let mut hasher = StableHasher::new();
+                hcx.while_hashing_spans(false, |hcx| {
+                    hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+                        kind.hash_stable(hcx, &mut hasher)
+                    })
+                });
+                hasher.finish()
+            };
+            stable_hash.hash_stable(hcx, hasher);
+        } else {
+            stable_hash.hash_stable(hcx, hasher);
+        }
     }
 }
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 6e4907fe518..d94ad7ba71a 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1111,24 +1111,55 @@ impl CheckAttrVisitor<'_> {
     }
 
     /// Warns against some misuses of `#[must_use]`
-    fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, _target: Target) -> bool {
+    fn check_must_use(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
         let node = self.tcx.hir().get(hir_id);
-        if let Some(fn_node) = node.fn_kind() {
-            if let rustc_hir::IsAsync::Async = fn_node.asyncness() {
-                self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
-                    lint.build(
-                        "`must_use` attribute on `async` functions \
-                              applies to the anonymous `Future` returned by the \
-                              function, not the value within",
-                    )
-                    .span_label(
-                        span,
-                        "this attribute does nothing, the `Future`s \
-                                returned by async functions are already `must_use`",
-                    )
-                    .emit();
-                });
-            }
+        if let Some(kind) = node.fn_kind() && let rustc_hir::IsAsync::Async = kind.asyncness() {
+            self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+                lint.build(
+                    "`must_use` attribute on `async` functions \
+                    applies to the anonymous `Future` returned by the \
+                    function, not the value within",
+                )
+                .span_label(
+                    span,
+                    "this attribute does nothing, the `Future`s \
+                    returned by async functions are already `must_use`",
+                )
+                .emit();
+            });
+        }
+
+        if !matches!(
+            target,
+            Target::Fn
+                | Target::Enum
+                | Target::Struct
+                | Target::Union
+                | Target::Method(_)
+                | Target::ForeignFn
+                // `impl Trait` in return position can trip
+                // `unused_must_use` if `Trait` is marked as
+                // `#[must_use]`
+                | Target::Trait
+        ) {
+            let article = match target {
+                Target::ExternCrate
+                | Target::OpaqueTy
+                | Target::Enum
+                | Target::Impl
+                | Target::Expression
+                | Target::Arm
+                | Target::AssocConst
+                | Target::AssocTy => "an",
+                _ => "a",
+            };
+
+            self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
+                lint.build(&format!(
+                    "`#[must_use]` has no effect when applied to {article} {target}"
+                ))
+                .emit();
+            });
         }
 
         // For now, its always valid
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index e52fbc8ab92..e438b521a95 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -683,34 +683,33 @@ impl<'tcx> DeadVisitor<'tcx> {
                 let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
                 let mut err = lint.build(&format!("{} is never {}: `{}`", descr, participle, name));
                 let hir = self.tcx.hir();
-                if let Some(encl_scope) = hir.get_enclosing_scope(id) {
-                    if let Some(encl_def_id) = hir.opt_local_def_id(encl_scope) {
-                        if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
-                            let traits_str = ign_traits
-                                .iter()
-                                .map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id)))
-                                .collect::<Vec<_>>()
-                                .join(" and ");
-                            let plural_s = pluralize!(ign_traits.len());
-                            let article = if ign_traits.len() > 1 { "" } else { "a " };
-                            let is_are = if ign_traits.len() > 1 { "these are" } else { "this is" };
-                            let msg = format!(
-                                "`{}` has {}derived impl{} for the trait{} {}, but {} \
-                                 intentionally ignored during dead code analysis",
-                                self.tcx.item_name(encl_def_id.to_def_id()),
-                                article,
-                                plural_s,
-                                plural_s,
-                                traits_str,
-                                is_are
-                            );
-                            let multispan = ign_traits
-                                .iter()
-                                .map(|(_, impl_id)| self.tcx.def_span(*impl_id))
-                                .collect::<Vec<_>>();
-                            err.span_note(multispan, &msg);
-                        }
-                    }
+                if let Some(encl_scope) = hir.get_enclosing_scope(id)
+                    && let Some(encl_def_id) = hir.opt_local_def_id(encl_scope)
+                    && let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id)
+                {
+                    let traits_str = ign_traits
+                        .iter()
+                        .map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id)))
+                        .collect::<Vec<_>>()
+                        .join(" and ");
+                    let plural_s = pluralize!(ign_traits.len());
+                    let article = if ign_traits.len() > 1 { "" } else { "a " };
+                    let is_are = if ign_traits.len() > 1 { "these are" } else { "this is" };
+                    let msg = format!(
+                        "`{}` has {}derived impl{} for the trait{} {}, but {} \
+                        intentionally ignored during dead code analysis",
+                        self.tcx.item_name(encl_def_id.to_def_id()),
+                        article,
+                        plural_s,
+                        plural_s,
+                        traits_str,
+                        is_are
+                    );
+                    let multispan = ign_traits
+                        .iter()
+                        .map(|(_, impl_id)| self.tcx.def_span(*impl_id))
+                        .collect::<Vec<_>>();
+                    err.span_note(multispan, &msg);
                 }
                 err.emit();
             });
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 71381f1d869..71d49d8b7ea 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -4,16 +4,17 @@
 //!
 //! This API is completely unstable and subject to change.
 
+#![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(crate_visibility_modifier)]
 #![feature(iter_intersperse)]
 #![feature(let_else)]
+#![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
 #![feature(nll)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index a959089ebb3..ea99a90e937 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -332,12 +332,11 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
         let def_id = local_def_id.to_def_id();
 
         // Don't run unused pass for #[derive()]
-        if let Some(parent) = self.tcx.parent(def_id) {
-            if let DefKind::Impl = self.tcx.def_kind(parent.expect_local()) {
-                if self.tcx.has_attr(parent, sym::automatically_derived) {
-                    return;
-                }
-            }
+        if let Some(parent) = self.tcx.parent(def_id)
+            && let DefKind::Impl = self.tcx.def_kind(parent.expect_local())
+            && self.tcx.has_attr(parent, sym::automatically_derived)
+        {
+            return;
         }
 
         // Don't run unused pass for #[naked]
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index adbfb4fcf01..b520e5d04ea 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -94,24 +94,22 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
             _ => None,
         };
 
-        if let Some(res) = res {
-            if let Some(def_id) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
-                if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
-                    self.worklist.push(def_id);
-                } else {
-                    match res {
-                        // If this path leads to a constant, then we need to
-                        // recurse into the constant to continue finding
-                        // items that are reachable.
-                        Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
-                            self.worklist.push(def_id);
-                        }
+        if let Some(res) = res && let Some(def_id) = res.opt_def_id().and_then(|el| el.as_local()) {
+            if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
+                self.worklist.push(def_id);
+            } else {
+                match res {
+                    // If this path leads to a constant, then we need to
+                    // recurse into the constant to continue finding
+                    // items that are reachable.
+                    Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
+                        self.worklist.push(def_id);
+                    }
 
-                        // If this wasn't a static, then the destination is
-                        // surely reachable.
-                        _ => {
-                            self.reachable_symbols.insert(def_id);
-                        }
+                    // If this wasn't a static, then the destination is
+                    // surely reachable.
+                    _ => {
+                        self.reachable_symbols.insert(def_id);
                     }
                 }
             }
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 47bf0fe1221..6e526bf8fc7 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -216,7 +216,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
         Ok(self)
     }
 
-    fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
+    fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
         match *ty.kind() {
             // Print all nominal types as paths (unlike `pretty_print_type`).
             ty::FnDef(def_id, substs)
@@ -224,6 +224,24 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
             | ty::Closure(def_id, substs)
             | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
+
+            // The `pretty_print_type` formatting of array size depends on
+            // -Zverbose flag, so we cannot reuse it here.
+            ty::Array(ty, size) => {
+                self.write_str("[")?;
+                self = self.print_type(ty)?;
+                self.write_str("; ")?;
+                if let Some(size) = size.val().try_to_bits(self.tcx().data_layout.pointer_size) {
+                    write!(self, "{}", size)?
+                } else if let ty::ConstKind::Param(param) = size.val() {
+                    self = param.print(self)?
+                } else {
+                    self.write_str("_")?
+                }
+                self.write_str("]")?;
+                Ok(self)
+            }
+
             _ => self.pretty_print_type(ty),
         }
     }
@@ -245,12 +263,22 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
 
     fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
         // only print integers
-        if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int { .. })) = ct.val() {
-            if ct.ty().is_integral() {
-                return self.pretty_print_const(ct, true);
+        match (ct.val(), ct.ty().kind()) {
+            (
+                ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int(scalar))),
+                ty::Int(_) | ty::Uint(_),
+            ) => {
+                // The `pretty_print_const` formatting depends on -Zverbose
+                // flag, so we cannot reuse it here.
+                let signed = matches!(ct.ty().kind(), ty::Int(_));
+                write!(
+                    self,
+                    "{:#?}",
+                    ty::ConstInt::new(scalar, signed, ct.ty().is_ptr_sized_integral())
+                )?;
             }
+            _ => self.write_str("_")?,
         }
-        self.write_str("_")?;
         Ok(self)
     }
 
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index faead1bf5cd..3b644099ecf 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -470,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        let self_ty = self.typeck_results.borrow().node_type(method_expr[0].hir_id);
+        let self_ty = self.typeck_results.borrow().expr_ty(&method_expr[0]);
         let self_ty = format!("{:?}", self_ty);
         let name = method_path.ident.name;
         let is_as_ref_able = (self_ty.starts_with("&std::option::Option")
@@ -566,7 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'tcx>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
-    ) -> Option<(Span, &'static str, String, Applicability, bool /* verbose */)> {
+    ) -> Option<(Span, String, String, Applicability, bool /* verbose */)> {
         let sess = self.sess();
         let sp = expr.span;
 
@@ -594,7 +594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let pos = sp.lo() + BytePos(1);
                                 return Some((
                                     sp.with_hi(pos),
-                                    "consider removing the leading `b`",
+                                    "consider removing the leading `b`".to_string(),
                                     String::new(),
                                     Applicability::MachineApplicable,
                                     true,
@@ -608,7 +608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     {
                                 return Some((
                                     sp.shrink_to_lo(),
-                                    "consider adding a leading `b`",
+                                    "consider adding a leading `b`".to_string(),
                                     "b".to_string(),
                                     Applicability::MachineApplicable,
                                     true,
@@ -668,7 +668,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(sugg) = self.can_use_as_ref(expr) {
                             return Some((
                                 sugg.0,
-                                sugg.1,
+                                sugg.1.to_string(),
                                 sugg.2,
                                 Applicability::MachineApplicable,
                                 false,
@@ -696,7 +696,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     return Some((
                                         left_expr.span.shrink_to_lo(),
                                         "consider dereferencing here to assign to the mutable \
-                                         borrowed piece of memory",
+                                         borrowed piece of memory"
+                                            .to_string(),
                                         "*".to_string(),
                                         Applicability::MachineApplicable,
                                         true,
@@ -708,14 +709,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         return Some(match mutability {
                             hir::Mutability::Mut => (
                                 sp,
-                                "consider mutably borrowing here",
+                                "consider mutably borrowing here".to_string(),
                                 format!("{}&mut {}", prefix, sugg_expr),
                                 Applicability::MachineApplicable,
                                 false,
                             ),
                             hir::Mutability::Not => (
                                 sp,
-                                "consider borrowing here",
+                                "consider borrowing here".to_string(),
                                 format!("{}&{}", prefix, sugg_expr),
                                 Applicability::MachineApplicable,
                                 false,
@@ -744,7 +745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if sm.span_to_snippet(call_span).is_ok() {
                             return Some((
                                 sp.with_hi(call_span.lo()),
-                                "consider removing the borrow",
+                                "consider removing the borrow".to_string(),
                                 String::new(),
                                 Applicability::MachineApplicable,
                                 true,
@@ -757,7 +758,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if sm.span_to_snippet(expr.span).is_ok() {
                         return Some((
                             sp.with_hi(expr.span.lo()),
-                            "consider removing the borrow",
+                            "consider removing the borrow".to_string(),
                             String::new(),
                             Applicability::MachineApplicable,
                             true,
@@ -823,7 +824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             } {
                                 return Some((
                                     span,
-                                    "consider dereferencing",
+                                    "consider dereferencing".to_string(),
                                     src,
                                     applicability,
                                     true,
@@ -834,60 +835,93 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             _ if sp == expr.span => {
-                if let Some(steps) = self.deref_steps(checked_ty, expected) {
-                    let expr = expr.peel_blocks();
+                if let Some(mut steps) = self.deref_steps(checked_ty, expected) {
+                    let mut expr = expr.peel_blocks();
+                    let mut prefix_span = expr.span.shrink_to_lo();
+                    let mut remove = String::new();
 
-                    if steps == 1 {
+                    // Try peeling off any existing `&` and `&mut` to reach our target type
+                    while steps > 0 {
                         if let hir::ExprKind::AddrOf(_, mutbl, inner) = expr.kind {
                             // If the expression has `&`, removing it would fix the error
-                            let prefix_span = expr.span.with_hi(inner.span.lo());
-                            let message = match mutbl {
-                                hir::Mutability::Not => "consider removing the `&`",
-                                hir::Mutability::Mut => "consider removing the `&mut`",
+                            prefix_span = prefix_span.with_hi(inner.span.lo());
+                            expr = inner;
+                            remove += match mutbl {
+                                hir::Mutability::Not => "&",
+                                hir::Mutability::Mut => "&mut ",
                             };
-                            let suggestion = String::new();
-                            return Some((
-                                prefix_span,
-                                message,
-                                suggestion,
-                                Applicability::MachineApplicable,
-                                false,
-                            ));
+                            steps -= 1;
+                        } else {
+                            break;
                         }
-
-                        // For this suggestion to make sense, the type would need to be `Copy`,
-                        // or we have to be moving out of a `Box<T>`
-                        if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp)
-                            || checked_ty.is_box()
-                        {
-                            let message = if checked_ty.is_box() {
-                                "consider unboxing the value"
-                            } else if checked_ty.is_region_ptr() {
-                                "consider dereferencing the borrow"
-                            } else {
-                                "consider dereferencing the type"
-                            };
-                            let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                                Some(ident) => format!("{}: ", ident),
-                                None => String::new(),
-                            };
-                            let (span, suggestion) = if self.is_else_if_block(expr) {
-                                // Don't suggest nonsense like `else *if`
-                                return None;
-                            } else if let Some(expr) = self.maybe_get_block_expr(expr) {
-                                // prefix should be empty here..
-                                (expr.span.shrink_to_lo(), "*".to_string())
+                    }
+                    // If we've reached our target type with just removing `&`, then just print now.
+                    if steps == 0 {
+                        return Some((
+                            prefix_span,
+                            format!("consider removing the `{}`", remove.trim()),
+                            String::new(),
+                            // Do not remove `&&` to get to bool, because it might be something like
+                            // { a } && b, which we have a separate fixup suggestion that is more
+                            // likely correct...
+                            if remove.trim() == "&&" && expected == self.tcx.types.bool {
+                                Applicability::MaybeIncorrect
                             } else {
-                                (expr.span.shrink_to_lo(), format!("{}*", prefix))
-                            };
-                            return Some((
-                                span,
-                                message,
-                                suggestion,
-                                Applicability::MachineApplicable,
-                                true,
-                            ));
-                        }
+                                Applicability::MachineApplicable
+                            },
+                            true,
+                        ));
+                    }
+
+                    // For this suggestion to make sense, the type would need to be `Copy`,
+                    // or we have to be moving out of a `Box<T>`
+                    if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp)
+                        // FIXME(compiler-errors): We can actually do this if the checked_ty is
+                        // `steps` layers of boxes, not just one, but this is easier and most likely.
+                        || (checked_ty.is_box() && steps == 1)
+                    {
+                        let deref_kind = if checked_ty.is_box() {
+                            "unboxing the value"
+                        } else if checked_ty.is_region_ptr() {
+                            "dereferencing the borrow"
+                        } else {
+                            "dereferencing the type"
+                        };
+
+                        // Suggest removing `&` if we have removed any, otherwise suggest just
+                        // dereferencing the remaining number of steps.
+                        let message = if remove.is_empty() {
+                            format!("consider {}", deref_kind)
+                        } else {
+                            format!(
+                                "consider removing the `{}` and {} instead",
+                                remove.trim(),
+                                deref_kind
+                            )
+                        };
+
+                        let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
+                            Some(ident) => format!("{}: ", ident),
+                            None => String::new(),
+                        };
+
+                        let (span, suggestion) = if self.is_else_if_block(expr) {
+                            // Don't suggest nonsense like `else *if`
+                            return None;
+                        } else if let Some(expr) = self.maybe_get_block_expr(expr) {
+                            // prefix should be empty here..
+                            (expr.span.shrink_to_lo(), "*".to_string())
+                        } else {
+                            (prefix_span, format!("{}{}", prefix, "*".repeat(steps)))
+                        };
+
+                        return Some((
+                            span,
+                            message,
+                            suggestion,
+                            Applicability::MachineApplicable,
+                            true,
+                        ));
                     }
                 }
             }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index f3aa40b9ad1..a8c9c699ceb 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1517,7 +1517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             } else {
                 self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {
-                    let base_ty = self.typeck_results.borrow().node_type(base_expr.hir_id);
+                    let base_ty = self.typeck_results.borrow().expr_ty(*base_expr);
                     let same_adt = match (adt_ty.kind(), base_ty.kind()) {
                         (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt => true,
                         _ => false,
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 5cb1fe8cd94..2c81745836c 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -313,15 +313,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ) => {
                         // A reborrow has no effect before a dereference.
                     }
-                    // Catch cases which have Deref(None)
-                    // having them slip to bug! causes ICE
-                    // see #94291 for more info
-                    (&[Adjustment { kind: Adjust::Deref(None), .. }], _) => {
-                        self.tcx.sess.delay_span_bug(
-                            DUMMY_SP,
-                            &format!("Can't compose Deref(None) expressions"),
-                        )
-                    }
                     // FIXME: currently we never try to compose autoderefs
                     // and ReifyFnPointer/UnsafeFnPointer, but we could.
                     _ => bug!(
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index f5d110903e6..3dfee99b835 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -133,7 +133,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expected_arg_count = formal_input_tys.len();
 
         // expected_count, arg_count, error_code, sugg_unit, sugg_tuple_wrap_args
-        let mut error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> = None;
+        let mut arg_count_error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> =
+            None;
 
         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
@@ -143,7 +144,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Tuple(arg_types) => {
                     // Argument length differs
                     if arg_types.len() != provided_args.len() {
-                        error = Some((arg_types.len(), provided_args.len(), "E0057", false, None));
+                        arg_count_error =
+                            Some((arg_types.len(), provided_args.len(), "E0057", false, None));
                     }
                     let expected_input_tys = match expected_input_tys.get(0) {
                         Some(&ty) => match ty.kind() {
@@ -174,7 +176,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if supplied_arg_count >= expected_arg_count {
                 (formal_input_tys.to_vec(), expected_input_tys)
             } else {
-                error = Some((expected_arg_count, supplied_arg_count, "E0060", false, None));
+                arg_count_error =
+                    Some((expected_arg_count, supplied_arg_count, "E0060", false, None));
                 (self.err_args(supplied_arg_count), vec![])
             }
         } else {
@@ -198,7 +201,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let sugg_tuple_wrap_args = self.suggested_tuple_wrap(expected_input_tys, provided_args);
 
-            error = Some((
+            arg_count_error = Some((
                 expected_arg_count,
                 supplied_arg_count,
                 "E0061",
@@ -231,6 +234,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // This is more complicated than just checking type equality, as arguments could be coerced
         // This version writes those types back so further type checking uses the narrowed types
         let demand_compatible = |idx, final_arg_types: &mut Vec<Option<(Ty<'tcx>, Ty<'tcx>)>>| {
+            // Do not check argument compatibility if the number of args do not match
+            if arg_count_error.is_some() {
+                return;
+            }
+
             let formal_input_ty: Ty<'tcx> = formal_input_tys[idx];
             let expected_input_ty: Ty<'tcx> = expected_input_tys[idx];
             let provided_arg = &provided_args[idx];
@@ -328,7 +336,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // If there was an error in parameter count, emit that here
-        if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) = error
+        if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) =
+            arg_count_error
         {
             let (span, start_span, args, ctor_of) = match &call_expr.kind {
                 hir::ExprKind::Call(
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 8cad4fc707e..523602d5b18 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -218,9 +218,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.check_ref(expr, found, expected)
         {
             if verbose {
-                err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+                err.span_suggestion_verbose(sp, &msg, suggestion, applicability);
             } else {
-                err.span_suggestion(sp, msg, suggestion, applicability);
+                err.span_suggestion(sp, &msg, suggestion, applicability);
             }
         } else if let (ty::FnDef(def_id, ..), true) =
             (&found.kind(), self.suggest_fn_call(err, expr, expected, found))
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 9ee88dd6014..2b8bbe19244 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -340,6 +340,32 @@ impl AtomicBool {
         unsafe { &mut *(v as *mut bool as *mut Self) }
     }
 
+    /// Get atomic access to a `&mut [bool]` slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(atomic_from_mut, scoped_threads)]
+    /// use std::sync::atomic::{AtomicBool, Ordering};
+    ///
+    /// let mut some_bools = [false; 10];
+    /// let a = &*AtomicBool::from_mut_slice(&mut some_bools);
+    /// std::thread::scope(|s| {
+    ///     for i in 0..a.len() {
+    ///         s.spawn(move |_| a[i].store(true, Ordering::Relaxed));
+    ///     }
+    /// });
+    /// assert_eq!(some_bools, [true; 10]);
+    /// ```
+    #[inline]
+    #[cfg(target_has_atomic_equal_alignment = "8")]
+    #[unstable(feature = "atomic_from_mut", issue = "76314")]
+    pub fn from_mut_slice(v: &mut [bool]) -> &mut [Self] {
+        // SAFETY: the mutable reference guarantees unique ownership, and
+        // alignment of both `bool` and `Self` is 1.
+        unsafe { &mut *(v as *mut [bool] as *mut [Self]) }
+    }
+
     /// Consumes the atomic and returns the contained value.
     ///
     /// This is safe because passing `self` by value guarantees that no other threads are
@@ -945,6 +971,42 @@ impl<T> AtomicPtr<T> {
         unsafe { &mut *(v as *mut *mut T as *mut Self) }
     }
 
+    /// Get atomic access to a slice of pointers.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(atomic_from_mut, scoped_threads)]
+    /// use std::ptr::null_mut;
+    /// use std::sync::atomic::{AtomicPtr, Ordering};
+    ///
+    /// let mut some_ptrs = [null_mut::<String>(); 10];
+    /// let a = &*AtomicPtr::from_mut_slice(&mut some_ptrs);
+    /// std::thread::scope(|s| {
+    ///     for i in 0..a.len() {
+    ///         s.spawn(move |_| {
+    ///             let name = Box::new(format!("thread{i}"));
+    ///             a[i].store(Box::into_raw(name), Ordering::Relaxed);
+    ///         });
+    ///     }
+    /// });
+    /// for p in some_ptrs {
+    ///     assert!(!p.is_null());
+    ///     let name = unsafe { Box::from_raw(p) };
+    ///     println!("Hello, {name}!");
+    /// }
+    /// ```
+    #[inline]
+    #[cfg(target_has_atomic_equal_alignment = "ptr")]
+    #[unstable(feature = "atomic_from_mut", issue = "76314")]
+    pub fn from_mut_slice(v: &mut [*mut T]) -> &mut [Self] {
+        // SAFETY:
+        //  - the mutable reference guarantees unique ownership.
+        //  - the alignment of `*mut T` and `Self` is the same on all platforms
+        //    supported by rust, as verified above.
+        unsafe { &mut *(v as *mut [*mut T] as *mut [Self]) }
+    }
+
     /// Consumes the atomic and returns the contained value.
     ///
     /// This is safe because passing `self` by value guarantees that no other threads are
@@ -1459,6 +1521,38 @@ macro_rules! atomic_int {
                 unsafe { &mut *(v as *mut $int_type as *mut Self) }
             }
 
+            #[doc = concat!("Get atomic access to a `&mut [", stringify!($int_type), "]` slice.")]
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(atomic_from_mut, scoped_threads)]
+            #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
+            ///
+            /// let mut some_ints = [0; 10];
+            #[doc = concat!("let a = &*", stringify!($atomic_type), "::from_mut_slice(&mut some_ints);")]
+            /// std::thread::scope(|s| {
+            ///     for i in 0..a.len() {
+            ///         s.spawn(move |_| a[i].store(i as _, Ordering::Relaxed));
+            ///     }
+            /// });
+            /// for (i, n) in some_ints.into_iter().enumerate() {
+            ///     assert_eq!(i, n as usize);
+            /// }
+            /// ```
+            #[inline]
+            #[$cfg_align]
+            #[unstable(feature = "atomic_from_mut", issue = "76314")]
+            pub fn from_mut_slice(v: &mut [$int_type]) -> &mut [Self] {
+                use crate::mem::align_of;
+                let [] = [(); align_of::<Self>() - align_of::<$int_type>()];
+                // SAFETY:
+                //  - the mutable reference guarantees unique ownership.
+                //  - the alignment of `$int_type` and `Self` is the
+                //    same, as promised by $cfg_align and verified above.
+                unsafe { &mut *(v as *mut [$int_type] as *mut [Self]) }
+            }
+
             /// Consumes the atomic and returns the contained value.
             ///
             /// This is safe because passing `self` by value guarantees that no other threads are
diff --git a/library/portable-simd/crates/core_simd/examples/spectral_norm.rs b/library/portable-simd/crates/core_simd/examples/spectral_norm.rs
new file mode 100644
index 00000000000..c515dad4dea
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/examples/spectral_norm.rs
@@ -0,0 +1,77 @@
+#![feature(portable_simd)]
+
+use core_simd::simd::*;
+
+fn a(i: usize, j: usize) -> f64 {
+    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
+}
+
+fn mult_av(v: &[f64], out: &mut [f64]) {
+    assert!(v.len() == out.len());
+    assert!(v.len() % 2 == 0);
+
+    for (i, out) in out.iter_mut().enumerate() {
+        let mut sum = f64x2::splat(0.0);
+
+        let mut j = 0;
+        while j < v.len() {
+            let b = f64x2::from_slice(&v[j..]);
+            let a = f64x2::from_array([a(i, j), a(i, j + 1)]);
+            sum += b / a;
+            j += 2
+        }
+        *out = sum.horizontal_sum();
+    }
+}
+
+fn mult_atv(v: &[f64], out: &mut [f64]) {
+    assert!(v.len() == out.len());
+    assert!(v.len() % 2 == 0);
+
+    for (i, out) in out.iter_mut().enumerate() {
+        let mut sum = f64x2::splat(0.0);
+
+        let mut j = 0;
+        while j < v.len() {
+            let b = f64x2::from_slice(&v[j..]);
+            let a = f64x2::from_array([a(j, i), a(j + 1, i)]);
+            sum += b / a;
+            j += 2
+        }
+        *out = sum.horizontal_sum();
+    }
+}
+
+fn mult_atav(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
+    mult_av(v, tmp);
+    mult_atv(tmp, out);
+}
+
+pub fn spectral_norm(n: usize) -> f64 {
+    assert!(n % 2 == 0, "only even lengths are accepted");
+
+    let mut u = vec![1.0; n];
+    let mut v = u.clone();
+    let mut tmp = u.clone();
+
+    for _ in 0..10 {
+        mult_atav(&u, &mut v, &mut tmp);
+        mult_atav(&v, &mut u, &mut tmp);
+    }
+    (dot(&u, &v) / dot(&v, &v)).sqrt()
+}
+
+fn dot(x: &[f64], y: &[f64]) -> f64 {
+    // This is auto-vectorized:
+    x.iter().zip(y).map(|(&x, &y)| x * y).sum()
+}
+
+#[cfg(test)]
+#[test]
+fn test() {
+    assert_eq!(&format!("{:.9}", spectral_norm(100)), "1.274219991");
+}
+
+fn main() {
+    // Empty main to make cargo happy
+}
diff --git a/library/portable-simd/crates/core_simd/src/comparisons.rs b/library/portable-simd/crates/core_simd/src/comparisons.rs
index edef5af3687..d024cf4ddbe 100644
--- a/library/portable-simd/crates/core_simd/src/comparisons.rs
+++ b/library/portable-simd/crates/core_simd/src/comparisons.rs
@@ -10,6 +10,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_eq(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_eq(self, other)) }
     }
 
@@ -17,6 +19,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_ne(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_ne(self, other)) }
     }
 }
@@ -30,6 +34,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_lt(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_lt(self, other)) }
     }
 
@@ -37,6 +43,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_gt(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_gt(self, other)) }
     }
 
@@ -44,6 +52,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_le(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_le(self, other)) }
     }
 
@@ -51,6 +61,8 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn lanes_ge(self, other: Self) -> Mask<T::Mask, LANES> {
+        // Safety: `self` is a vector, and the result of the comparison
+        // is always a valid mask.
         unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
     }
 }
diff --git a/library/portable-simd/crates/core_simd/src/intrinsics.rs b/library/portable-simd/crates/core_simd/src/intrinsics.rs
index 2291400537c..4c68d11e893 100644
--- a/library/portable-simd/crates/core_simd/src/intrinsics.rs
+++ b/library/portable-simd/crates/core_simd/src/intrinsics.rs
@@ -2,31 +2,55 @@
 //! crate.
 //!
 //! The LLVM assembly language is documented here: <https://llvm.org/docs/LangRef.html>
+//!
+//! A quick glossary of jargon that may appear in this module, mostly paraphrasing LLVM's LangRef:
+//! - poison: "undefined behavior as a value". specifically, it is like uninit memory (such as padding bytes). it is "safe" to create poison, BUT
+//!   poison MUST NOT be observed from safe code, as operations on poison return poison, like NaN. unlike NaN, which has defined comparisons,
+//!   poison is neither true nor false, and LLVM may also convert it to undef (at which point it is both). so, it can't be conditioned on, either.
+//! - undef: "a value that is every value". functionally like poison, insofar as Rust is concerned. poison may become this. note:
+//!   this means that division by poison or undef is like division by zero, which means it inflicts...
+//! - "UB": poison and undef cover most of what people call "UB". "UB" means this operation immediately invalidates the program:
+//!   LLVM is allowed to lower it to `ud2` or other opcodes that may cause an illegal instruction exception, and this is the "good end".
+//!   The "bad end" is that LLVM may reverse time to the moment control flow diverged on a path towards undefined behavior,
+//!   and destroy the other branch, potentially deleting safe code and violating Rust's `unsafe` contract.
+//!
+//! Note that according to LLVM, vectors are not arrays, but they are equivalent when stored to and loaded from memory.
+//!
+//! Unless stated otherwise, all intrinsics for binary operations require SIMD vectors of equal types and lengths.
 
 /// These intrinsics aren't linked directly from LLVM and are mostly undocumented, however they are
-/// simply lowered to the matching LLVM instructions by the compiler.  The associated instruction
-/// is documented alongside each intrinsic.
+/// mostly lowered to the matching LLVM instructions by the compiler in a fairly straightforward manner.
+/// The associated LLVM instruction or intrinsic is documented alongside each Rust intrinsic function.
 extern "platform-intrinsic" {
     /// add/fadd
     pub(crate) fn simd_add<T>(x: T, y: T) -> T;
 
     /// sub/fsub
-    pub(crate) fn simd_sub<T>(x: T, y: T) -> T;
+    pub(crate) fn simd_sub<T>(lhs: T, rhs: T) -> T;
 
     /// mul/fmul
     pub(crate) fn simd_mul<T>(x: T, y: T) -> T;
 
     /// udiv/sdiv/fdiv
-    pub(crate) fn simd_div<T>(x: T, y: T) -> T;
+    /// ints and uints: {s,u}div incur UB if division by zero occurs.
+    /// ints: sdiv is UB for int::MIN / -1.
+    /// floats: fdiv is never UB, but may create NaNs or infinities.
+    pub(crate) fn simd_div<T>(lhs: T, rhs: T) -> T;
 
     /// urem/srem/frem
-    pub(crate) fn simd_rem<T>(x: T, y: T) -> T;
+    /// ints and uints: {s,u}rem incur UB if division by zero occurs.
+    /// ints: srem is UB for int::MIN / -1.
+    /// floats: frem is equivalent to libm::fmod in the "default" floating point environment, sans errno.
+    pub(crate) fn simd_rem<T>(lhs: T, rhs: T) -> T;
 
     /// shl
-    pub(crate) fn simd_shl<T>(x: T, y: T) -> T;
+    /// for (u)ints. poison if rhs >= lhs::BITS
+    pub(crate) fn simd_shl<T>(lhs: T, rhs: T) -> T;
 
-    /// lshr/ashr
-    pub(crate) fn simd_shr<T>(x: T, y: T) -> T;
+    /// ints: ashr
+    /// uints: lshr
+    /// poison if rhs >= lhs::BITS
+    pub(crate) fn simd_shr<T>(lhs: T, rhs: T) -> T;
 
     /// and
     pub(crate) fn simd_and<T>(x: T, y: T) -> T;
@@ -38,12 +62,18 @@ extern "platform-intrinsic" {
     pub(crate) fn simd_xor<T>(x: T, y: T) -> T;
 
     /// fptoui/fptosi/uitofp/sitofp
+    /// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5
+    /// but the truncated value must fit in the target type or the result is poison.
+    /// use `simd_as` instead for a cast that performs a saturating conversion.
     pub(crate) fn simd_cast<T, U>(x: T) -> U;
     /// follows Rust's `T as U` semantics, including saturating float casts
     /// which amounts to the same as `simd_cast` for many cases
     pub(crate) fn simd_as<T, U>(x: T) -> U;
 
     /// neg/fneg
+    /// ints: ultimately becomes a call to cg_ssa's BuilderMethods::neg. cg_llvm equates this to `simd_sub(Simd::splat(0), x)`.
+    /// floats: LLVM's fneg, which changes the floating point sign bit. Some arches have instructions for it.
+    /// Rust panics for Neg::neg(int::MIN) due to overflow, but it is not UB in LLVM without `nsw`.
     pub(crate) fn simd_neg<T>(x: T) -> T;
 
     /// fabs
@@ -53,6 +83,7 @@ extern "platform-intrinsic" {
     pub(crate) fn simd_fmin<T>(x: T, y: T) -> T;
     pub(crate) fn simd_fmax<T>(x: T, y: T) -> T;
 
+    // these return Simd<int, N> with the same BITS size as the inputs
     pub(crate) fn simd_eq<T, U>(x: T, y: T) -> U;
     pub(crate) fn simd_ne<T, U>(x: T, y: T) -> U;
     pub(crate) fn simd_lt<T, U>(x: T, y: T) -> U;
@@ -61,19 +92,31 @@ extern "platform-intrinsic" {
     pub(crate) fn simd_ge<T, U>(x: T, y: T) -> U;
 
     // shufflevector
+    // idx: LLVM calls it a "shuffle mask vector constant", a vector of i32s
     pub(crate) fn simd_shuffle<T, U, V>(x: T, y: T, idx: U) -> V;
 
+    /// llvm.masked.gather
+    /// like a loop of pointer reads
+    /// val: vector of values to select if a lane is masked
+    /// ptr: vector of pointers to read from
+    /// mask: a "wide" mask of integers, selects as if simd_select(mask, read(ptr), val)
+    /// note, the LLVM intrinsic accepts a mask vector of <N x i1>
+    /// FIXME: review this if/when we fix up our mask story in general?
     pub(crate) fn simd_gather<T, U, V>(val: T, ptr: U, mask: V) -> T;
+    /// llvm.masked.scatter
+    /// like gather, but more spicy, as it writes instead of reads
     pub(crate) fn simd_scatter<T, U, V>(val: T, ptr: U, mask: V);
 
     // {s,u}add.sat
     pub(crate) fn simd_saturating_add<T>(x: T, y: T) -> T;
 
     // {s,u}sub.sat
-    pub(crate) fn simd_saturating_sub<T>(x: T, y: T) -> T;
+    pub(crate) fn simd_saturating_sub<T>(lhs: T, rhs: T) -> T;
 
     // reductions
+    // llvm.vector.reduce.{add,fadd}
     pub(crate) fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
+    // llvm.vector.reduce.{mul,fmul}
     pub(crate) fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
     #[allow(unused)]
     pub(crate) fn simd_reduce_all<T>(x: T) -> bool;
@@ -90,7 +133,10 @@ extern "platform-intrinsic" {
     pub(crate) fn simd_bitmask<T, U>(x: T) -> U;
 
     // select
-    pub(crate) fn simd_select<M, T>(m: M, a: T, b: T) -> T;
+    // first argument is a vector of integers, -1 (all bits 1) is "true"
+    // logically equivalent to (yes & m) | (no & (m^-1),
+    // but you can use it on floats.
+    pub(crate) fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
     #[allow(unused)]
-    pub(crate) fn simd_select_bitmask<M, T>(m: M, a: T, b: T) -> T;
+    pub(crate) fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
 }
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index 960a6640083..91ae34c05e0 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -1,7 +1,9 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![feature(
     const_fn_trait_bound,
+    convert_float_to_int,
     decl_macro,
+    intra_doc_pointers,
     platform_intrinsics,
     repr_simd,
     simd_ffi,
diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs
index ae1fef53da8..e1cd7930450 100644
--- a/library/portable-simd/crates/core_simd/src/masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks.rs
@@ -12,8 +12,10 @@
 )]
 mod mask_impl;
 
-use crate::simd::intrinsics;
-use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
+mod to_bitmask;
+pub use to_bitmask::ToBitMask;
+
+use crate::simd::{intrinsics, LaneCount, Simd, SimdElement, SupportedLaneCount};
 use core::cmp::Ordering;
 use core::{fmt, mem};
 
@@ -42,6 +44,9 @@ mod sealed {
 use sealed::Sealed;
 
 /// Marker trait for types that may be used as SIMD mask elements.
+///
+/// # Safety
+/// Type must be a signed integer.
 pub unsafe trait MaskElement: SimdElement + Sealed {}
 
 macro_rules! impl_element {
@@ -149,6 +154,7 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self {
+        // Safety: the caller must confirm this invariant
         unsafe { Self(mask_impl::Mask::from_int_unchecked(value)) }
     }
 
@@ -161,6 +167,7 @@ where
     #[must_use = "method returns a new mask and does not mutate the original value"]
     pub fn from_int(value: Simd<T, LANES>) -> Self {
         assert!(T::valid(value), "all values must be either 0 or -1",);
+        // Safety: the validity has been checked
         unsafe { Self::from_int_unchecked(value) }
     }
 
@@ -179,6 +186,7 @@ where
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
     pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
+        // Safety: the caller must confirm this invariant
         unsafe { self.0.test_unchecked(lane) }
     }
 
@@ -190,6 +198,7 @@ where
     #[must_use = "method returns a new bool and does not mutate the original value"]
     pub fn test(&self, lane: usize) -> bool {
         assert!(lane < LANES, "lane index out of range");
+        // Safety: the lane index has been checked
         unsafe { self.test_unchecked(lane) }
     }
 
@@ -199,6 +208,7 @@ where
     /// `lane` must be less than `LANES`.
     #[inline]
     pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
+        // Safety: the caller must confirm this invariant
         unsafe {
             self.0.set_unchecked(lane, value);
         }
@@ -211,27 +221,12 @@ where
     #[inline]
     pub fn set(&mut self, lane: usize, value: bool) {
         assert!(lane < LANES, "lane index out of range");
+        // Safety: the lane index has been checked
         unsafe {
             self.set_unchecked(lane, value);
         }
     }
 
-    /// Convert this mask to a bitmask, with one bit set per lane.
-    #[cfg(feature = "generic_const_exprs")]
-    #[inline]
-    #[must_use = "method returns a new array and does not mutate the original value"]
-    pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
-        self.0.to_bitmask()
-    }
-
-    /// Convert a bitmask to a mask.
-    #[cfg(feature = "generic_const_exprs")]
-    #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
-        Self(mask_impl::Mask::from_bitmask(bitmask))
-    }
-
     /// Returns true if any lane is set, or false otherwise.
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
index b4217dc87ba..ec4dd357ee9 100644
--- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
@@ -1,7 +1,7 @@
 #![allow(unused_imports)]
 use super::MaskElement;
 use crate::simd::intrinsics;
-use crate::simd::{LaneCount, Simd, SupportedLaneCount};
+use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask};
 use core::marker::PhantomData;
 
 /// A mask where each lane is represented by a single bit.
@@ -115,20 +115,22 @@ where
         unsafe { Self(intrinsics::simd_bitmask(value), PhantomData) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
-    #[must_use = "method returns a new array and does not mutate the original value"]
-    pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
-        // Safety: these are the same type and we are laundering the generic
+    pub fn to_bitmask_integer<U>(self) -> U
+    where
+        super::Mask<T, LANES>: ToBitMask<BitMask = U>,
+    {
+        // Safety: these are the same types
         unsafe { core::mem::transmute_copy(&self.0) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
-        // Safety: these are the same type and we are laundering the generic
-        Self(unsafe { core::mem::transmute_copy(&bitmask) }, PhantomData)
+    pub fn from_bitmask_integer<U>(bitmask: U) -> Self
+    where
+        super::Mask<T, LANES>: ToBitMask<BitMask = U>,
+    {
+        // Safety: these are the same types
+        unsafe { Self(core::mem::transmute_copy(&bitmask), PhantomData) }
     }
 
     #[inline]
@@ -137,6 +139,7 @@ where
     where
         U: MaskElement,
     {
+        // Safety: bitmask layout does not depend on the element width
         unsafe { core::mem::transmute_copy(&self) }
     }
 
diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
index e5bb784bb91..8bbdf637de8 100644
--- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
@@ -2,7 +2,7 @@
 
 use super::MaskElement;
 use crate::simd::intrinsics;
-use crate::simd::{LaneCount, Simd, SupportedLaneCount};
+use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask};
 
 #[repr(transparent)]
 pub struct Mask<T, const LANES: usize>(Simd<T, LANES>)
@@ -66,6 +66,23 @@ where
     }
 }
 
+// Used for bitmask bit order workaround
+pub(crate) trait ReverseBits {
+    fn reverse_bits(self) -> Self;
+}
+
+macro_rules! impl_reverse_bits {
+    { $($int:ty),* } => {
+        $(
+        impl ReverseBits for $int {
+            fn reverse_bits(self) -> Self { <$int>::reverse_bits(self) }
+        }
+        )*
+    }
+}
+
+impl_reverse_bits! { u8, u16, u32, u64 }
+
 impl<T, const LANES: usize> Mask<T, LANES>
 where
     T: MaskElement,
@@ -106,44 +123,40 @@ where
     where
         U: MaskElement,
     {
+        // Safety: masks are simply integer vectors of 0 and -1, and we can cast the element type.
         unsafe { Mask(intrinsics::simd_cast(self.0)) }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
-    #[must_use = "method returns a new array and does not mutate the original value"]
-    pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
-        unsafe {
-            let mut bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN] =
-                intrinsics::simd_bitmask(self.0);
-
-            // There is a bug where LLVM appears to implement this operation with the wrong
-            // bit order.
-            // TODO fix this in a better way
-            if cfg!(target_endian = "big") {
-                for x in bitmask.as_mut() {
-                    *x = x.reverse_bits();
-                }
-            }
+    pub(crate) fn to_bitmask_integer<U: ReverseBits>(self) -> U
+    where
+        super::Mask<T, LANES>: ToBitMask<BitMask = U>,
+    {
+        // Safety: U is required to be the appropriate bitmask type
+        let bitmask: U = unsafe { intrinsics::simd_bitmask(self.0) };
 
+        // LLVM assumes bit order should match endianness
+        if cfg!(target_endian = "big") {
+            bitmask.reverse_bits()
+        } else {
             bitmask
         }
     }
 
-    #[cfg(feature = "generic_const_exprs")]
     #[inline]
-    #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn from_bitmask(mut bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
-        unsafe {
-            // There is a bug where LLVM appears to implement this operation with the wrong
-            // bit order.
-            // TODO fix this in a better way
-            if cfg!(target_endian = "big") {
-                for x in bitmask.as_mut() {
-                    *x = x.reverse_bits();
-                }
-            }
+    pub(crate) fn from_bitmask_integer<U: ReverseBits>(bitmask: U) -> Self
+    where
+        super::Mask<T, LANES>: ToBitMask<BitMask = U>,
+    {
+        // LLVM assumes bit order should match endianness
+        let bitmask = if cfg!(target_endian = "big") {
+            bitmask.reverse_bits()
+        } else {
+            bitmask
+        };
 
+        // Safety: U is required to be the appropriate bitmask type
+        unsafe {
             Self::from_int_unchecked(intrinsics::simd_select_bitmask(
                 bitmask,
                 Self::splat(true).to_int(),
@@ -155,12 +168,14 @@ where
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
     pub fn any(self) -> bool {
+        // Safety: use `self` as an integer vector
         unsafe { intrinsics::simd_reduce_any(self.to_int()) }
     }
 
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original value"]
     pub fn all(self) -> bool {
+        // Safety: use `self` as an integer vector
         unsafe { intrinsics::simd_reduce_all(self.to_int()) }
     }
 }
@@ -184,6 +199,7 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     fn bitand(self, rhs: Self) -> Self {
+        // Safety: `self` is an integer vector
         unsafe { Self(intrinsics::simd_and(self.0, rhs.0)) }
     }
 }
@@ -197,6 +213,7 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     fn bitor(self, rhs: Self) -> Self {
+        // Safety: `self` is an integer vector
         unsafe { Self(intrinsics::simd_or(self.0, rhs.0)) }
     }
 }
@@ -210,6 +227,7 @@ where
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
     fn bitxor(self, rhs: Self) -> Self {
+        // Safety: `self` is an integer vector
         unsafe { Self(intrinsics::simd_xor(self.0, rhs.0)) }
     }
 }
diff --git a/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs
new file mode 100644
index 00000000000..1c2037764c1
--- /dev/null
+++ b/library/portable-simd/crates/core_simd/src/masks/to_bitmask.rs
@@ -0,0 +1,57 @@
+use super::{mask_impl, Mask, MaskElement};
+use crate::simd::{LaneCount, SupportedLaneCount};
+
+mod sealed {
+    pub trait Sealed {}
+}
+pub use sealed::Sealed;
+
+impl<T, const LANES: usize> Sealed for Mask<T, LANES>
+where
+    T: MaskElement,
+    LaneCount<LANES>: SupportedLaneCount,
+{
+}
+
+/// Converts masks to and from integer bitmasks.
+///
+/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB.
+///
+/// # Safety
+/// This trait is `unsafe` and sealed, since the `BitMask` type must match the number of lanes in
+/// the mask.
+pub unsafe trait ToBitMask: Sealed {
+    /// The integer bitmask type.
+    type BitMask;
+
+    /// Converts a mask to a bitmask.
+    fn to_bitmask(self) -> Self::BitMask;
+
+    /// Converts a bitmask to a mask.
+    fn from_bitmask(bitmask: Self::BitMask) -> Self;
+}
+
+macro_rules! impl_integer_intrinsic {
+    { $(unsafe impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => {
+        $(
+        unsafe impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
+            type BitMask = $int;
+
+            fn to_bitmask(self) -> $int {
+                self.0.to_bitmask_integer()
+            }
+
+            fn from_bitmask(bitmask: $int) -> Self {
+                Self(mask_impl::Mask::from_bitmask_integer(bitmask))
+            }
+        }
+        )*
+    }
+}
+
+impl_integer_intrinsic! {
+    unsafe impl ToBitMask<BitMask=u8> for Mask<_, 8>
+    unsafe impl ToBitMask<BitMask=u16> for Mask<_, 16>
+    unsafe impl ToBitMask<BitMask=u32> for Mask<_, 32>
+    unsafe impl ToBitMask<BitMask=u64> for Mask<_, 64>
+}
diff --git a/library/portable-simd/crates/core_simd/src/math.rs b/library/portable-simd/crates/core_simd/src/math.rs
index 7435b6df918..0b4e40983af 100644
--- a/library/portable-simd/crates/core_simd/src/math.rs
+++ b/library/portable-simd/crates/core_simd/src/math.rs
@@ -22,6 +22,7 @@ macro_rules! impl_uint_arith {
             /// ```
             #[inline]
             pub fn saturating_add(self, second: Self) -> Self {
+                // Safety: `self` is a vector
                 unsafe { simd_saturating_add(self, second) }
             }
 
@@ -41,6 +42,7 @@ macro_rules! impl_uint_arith {
             /// assert_eq!(sat, Simd::splat(0));
             #[inline]
             pub fn saturating_sub(self, second: Self) -> Self {
+                // Safety: `self` is a vector
                 unsafe { simd_saturating_sub(self, second) }
             }
         })+
@@ -68,6 +70,7 @@ macro_rules! impl_int_arith {
             /// ```
             #[inline]
             pub fn saturating_add(self, second: Self) -> Self {
+                // Safety: `self` is a vector
                 unsafe { simd_saturating_add(self, second) }
             }
 
@@ -87,6 +90,7 @@ macro_rules! impl_int_arith {
             /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0]));
             #[inline]
             pub fn saturating_sub(self, second: Self) -> Self {
+                // Safety: `self` is a vector
                 unsafe { simd_saturating_sub(self, second) }
             }
 
diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs
index b65038933bf..1b35b3e717a 100644
--- a/library/portable-simd/crates/core_simd/src/ops.rs
+++ b/library/portable-simd/crates/core_simd/src/ops.rs
@@ -57,29 +57,40 @@ macro_rules! wrap_bitshift {
     };
 }
 
-// Division by zero is poison, according to LLVM.
-// So is dividing the MIN value of a signed integer by -1,
-// since that would return MAX + 1.
-// FIXME: Rust allows <SInt>::MIN / -1,
-// so we should probably figure out how to make that safe.
+/// SAFETY: This macro must only be used to impl Div or Rem and given the matching intrinsic.
+/// It guards against LLVM's UB conditions for integer div or rem using masks and selects,
+/// thus guaranteeing a Rust value returns instead.
+///
+/// |                  | LLVM | Rust
+/// | :--------------: | :--- | :----------
+/// | N {/,%} 0        | UB   | panic!()
+/// | <$int>::MIN / -1 | UB   | <$int>::MIN
+/// | <$int>::MIN % -1 | UB   | 0
+///
 macro_rules! int_divrem_guard {
     (   $lhs:ident,
         $rhs:ident,
         {   const PANIC_ZERO: &'static str = $zero:literal;
-            const PANIC_OVERFLOW: &'static str = $overflow:literal;
             $simd_call:ident
         },
         $int:ident ) => {
         if $rhs.lanes_eq(Simd::splat(0)).any() {
             panic!($zero);
-        } else if <$int>::MIN != 0
-            && ($lhs.lanes_eq(Simd::splat(<$int>::MIN))
-                // type inference can break here, so cut an SInt to size
-                & $rhs.lanes_eq(Simd::splat(-1i64 as _))).any()
-        {
-            panic!($overflow);
         } else {
-            unsafe { $crate::simd::intrinsics::$simd_call($lhs, $rhs) }
+            // Prevent otherwise-UB overflow on the MIN / -1 case.
+            let rhs = if <$int>::MIN != 0 {
+                // This should, at worst, optimize to a few branchless logical ops
+                // Ideally, this entire conditional should evaporate
+                // Fire LLVM and implement those manually if it doesn't get the hint
+                ($lhs.lanes_eq(Simd::splat(<$int>::MIN))
+                // type inference can break here, so cut an SInt to size
+                & $rhs.lanes_eq(Simd::splat(-1i64 as _)))
+                .select(Simd::splat(1), $rhs)
+            } else {
+                // Nice base case to make it easy to const-fold away the other branch.
+                $rhs
+            };
+            unsafe { $crate::simd::intrinsics::$simd_call($lhs, rhs) }
         }
     };
 }
@@ -183,7 +194,6 @@ for_base_ops! {
     impl Div::div {
         int_divrem_guard {
             const PANIC_ZERO: &'static str = "attempt to divide by zero";
-            const PANIC_OVERFLOW: &'static str = "attempt to divide with overflow";
             simd_div
         }
     }
@@ -191,7 +201,6 @@ for_base_ops! {
     impl Rem::rem {
         int_divrem_guard {
             const PANIC_ZERO: &'static str = "attempt to calculate the remainder with a divisor of zero";
-            const PANIC_OVERFLOW: &'static str = "attempt to calculate the remainder with overflow";
             simd_rem
         }
     }
diff --git a/library/portable-simd/crates/core_simd/src/reduction.rs b/library/portable-simd/crates/core_simd/src/reduction.rs
index e79a185816b..e1cd743e442 100644
--- a/library/portable-simd/crates/core_simd/src/reduction.rs
+++ b/library/portable-simd/crates/core_simd/src/reduction.rs
@@ -14,24 +14,28 @@ macro_rules! impl_integer_reductions {
             /// Horizontal wrapping add.  Returns the sum of the lanes of the vector, with wrapping addition.
             #[inline]
             pub fn horizontal_sum(self) -> $scalar {
+                // Safety: `self` is an integer vector
                 unsafe { simd_reduce_add_ordered(self, 0) }
             }
 
             /// Horizontal wrapping multiply.  Returns the product of the lanes of the vector, with wrapping multiplication.
             #[inline]
             pub fn horizontal_product(self) -> $scalar {
+                // Safety: `self` is an integer vector
                 unsafe { simd_reduce_mul_ordered(self, 1) }
             }
 
             /// Horizontal maximum.  Returns the maximum lane in the vector.
             #[inline]
             pub fn horizontal_max(self) -> $scalar {
+                // Safety: `self` is an integer vector
                 unsafe { simd_reduce_max(self) }
             }
 
             /// Horizontal minimum.  Returns the minimum lane in the vector.
             #[inline]
             pub fn horizontal_min(self) -> $scalar {
+                // Safety: `self` is an integer vector
                 unsafe { simd_reduce_min(self) }
             }
         }
@@ -63,6 +67,7 @@ macro_rules! impl_float_reductions {
                 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
                     self.as_array().iter().sum()
                 } else {
+                    // Safety: `self` is a float vector
                     unsafe { simd_reduce_add_ordered(self, 0.) }
                 }
             }
@@ -74,6 +79,7 @@ macro_rules! impl_float_reductions {
                 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
                     self.as_array().iter().product()
                 } else {
+                    // Safety: `self` is a float vector
                     unsafe { simd_reduce_mul_ordered(self, 1.) }
                 }
             }
@@ -84,6 +90,7 @@ macro_rules! impl_float_reductions {
             /// return either.  This function will not return `NaN` unless all lanes are `NaN`.
             #[inline]
             pub fn horizontal_max(self) -> $scalar {
+                // Safety: `self` is a float vector
                 unsafe { simd_reduce_max(self) }
             }
 
@@ -93,6 +100,7 @@ macro_rules! impl_float_reductions {
             /// return either.  This function will not return `NaN` unless all lanes are `NaN`.
             #[inline]
             pub fn horizontal_min(self) -> $scalar {
+                // Safety: `self` is a float vector
                 unsafe { simd_reduce_min(self) }
             }
         }
diff --git a/library/portable-simd/crates/core_simd/src/round.rs b/library/portable-simd/crates/core_simd/src/round.rs
index 06ccab3ec49..556bc2cc1fe 100644
--- a/library/portable-simd/crates/core_simd/src/round.rs
+++ b/library/portable-simd/crates/core_simd/src/round.rs
@@ -1,9 +1,10 @@
 use crate::simd::intrinsics;
-use crate::simd::{LaneCount, Simd, SupportedLaneCount};
+use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
+use core::convert::FloatToInt;
 
 macro_rules! implement {
     {
-        $type:ty, $int_type:ty
+        $type:ty
     } => {
         impl<const LANES: usize> Simd<$type, LANES>
         where
@@ -18,20 +19,22 @@ macro_rules! implement {
             /// * Not be NaN
             /// * Not be infinite
             /// * Be representable in the return type, after truncating off its fractional part
+            ///
+            /// If these requirements are infeasible or costly, consider using the safe function [cast],
+            /// which saturates on conversion.
+            ///
+            /// [cast]: Simd::cast
             #[inline]
-            pub unsafe fn to_int_unchecked(self) -> Simd<$int_type, LANES> {
+            pub unsafe fn to_int_unchecked<I>(self) -> Simd<I, LANES>
+            where
+                $type: FloatToInt<I>,
+                I: SimdElement,
+            {
                 unsafe { intrinsics::simd_cast(self) }
             }
-
-            /// Creates a floating-point vector from an integer vector.  Rounds values that are
-            /// not exactly representable.
-            #[inline]
-            pub fn round_from_int(value: Simd<$int_type, LANES>) -> Self {
-                unsafe { intrinsics::simd_cast(value) }
-            }
         }
     }
 }
 
-implement! { f32, i32 }
-implement! { f64, i64 }
+implement! { f32 }
+implement! { f64 }
diff --git a/library/portable-simd/crates/core_simd/src/select.rs b/library/portable-simd/crates/core_simd/src/select.rs
index 8d521057fbd..3acf07260e1 100644
--- a/library/portable-simd/crates/core_simd/src/select.rs
+++ b/library/portable-simd/crates/core_simd/src/select.rs
@@ -11,6 +11,7 @@ where
     /// For each lane in the mask, choose the corresponding lane from `true_values` if
     /// that lane mask is true, and `false_values` if that lane mask is false.
     ///
+    /// # Examples
     /// ```
     /// # #![feature(portable_simd)]
     /// # #[cfg(feature = "std")] use core_simd::{Simd, Mask};
@@ -31,6 +32,8 @@ where
     where
         U: SimdElement<Mask = T>,
     {
+        // Safety: The mask has been cast to a vector of integers,
+        // and the operands to select between are vectors of the same type and length.
         unsafe { intrinsics::simd_select(self.to_int(), true_values, false_values) }
     }
 
@@ -39,6 +42,7 @@ where
     /// For each lane in the mask, choose the corresponding lane from `true_values` if
     /// that lane mask is true, and `false_values` if that lane mask is false.
     ///
+    /// # Examples
     /// ```
     /// # #![feature(portable_simd)]
     /// # #[cfg(feature = "std")] use core_simd::Mask;
diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs
index bdc489774a5..08b2add1166 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle.rs
@@ -95,6 +95,7 @@ pub trait Swizzle<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
         LaneCount<INPUT_LANES>: SupportedLaneCount,
         LaneCount<OUTPUT_LANES>: SupportedLaneCount,
     {
+        // Safety: `vector` is a vector, and `INDEX_IMPL` is a const array of u32.
         unsafe { intrinsics::simd_shuffle(vector, vector, Self::INDEX_IMPL) }
     }
 }
@@ -119,6 +120,7 @@ pub trait Swizzle2<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
         LaneCount<INPUT_LANES>: SupportedLaneCount,
         LaneCount<OUTPUT_LANES>: SupportedLaneCount,
     {
+        // Safety: `first` and `second` are vectors, and `INDEX_IMPL` is a const array of u32.
         unsafe { intrinsics::simd_shuffle(first, second, Self::INDEX_IMPL) }
     }
 }
diff --git a/library/portable-simd/crates/core_simd/src/to_bytes.rs b/library/portable-simd/crates/core_simd/src/to_bytes.rs
index 8d9b3e8ff85..b36b1a347b2 100644
--- a/library/portable-simd/crates/core_simd/src/to_bytes.rs
+++ b/library/portable-simd/crates/core_simd/src/to_bytes.rs
@@ -8,12 +8,14 @@ macro_rules! impl_to_bytes {
             /// Return the memory representation of this integer as a byte array in native byte
             /// order.
             pub fn to_ne_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
+                // Safety: transmuting between vectors is safe
                 unsafe { core::mem::transmute_copy(&self) }
             }
 
             /// Create a native endian integer value from its memory representation as a byte array
             /// in native endianness.
             pub fn from_ne_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
+                // Safety: transmuting between vectors is safe
                 unsafe { core::mem::transmute_copy(&bytes) }
             }
         }
diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs
index 35c5b6b84f8..3ccaf54b2a3 100644
--- a/library/portable-simd/crates/core_simd/src/vector.rs
+++ b/library/portable-simd/crates/core_simd/src/vector.rs
@@ -12,7 +12,79 @@ pub(crate) mod ptr;
 use crate::simd::intrinsics;
 use crate::simd::{LaneCount, Mask, MaskElement, SupportedLaneCount};
 
-/// A SIMD vector of `LANES` elements of type `T`.
+/// A SIMD vector of `LANES` elements of type `T`. `Simd<T, N>` has the same shape as [`[T; N]`](array), but operates like `T`.
+///
+/// Two vectors of the same type and length will, by convention, support the operators (+, *, etc.) that `T` does.
+/// These take the lanes at each index on the left-hand side and right-hand side, perform the operation,
+/// and return the result in the same lane in a vector of equal size. For a given operator, this is equivalent to zipping
+/// the two arrays together and mapping the operator over each lane.
+///
+/// ```rust
+/// # #![feature(array_zip, portable_simd)]
+/// # use core::simd::{Simd};
+/// let a0: [i32; 4] = [-2, 0, 2, 4];
+/// let a1 = [10, 9, 8, 7];
+/// let zm_add = a0.zip(a1).map(|(lhs, rhs)| lhs + rhs);
+/// let zm_mul = a0.zip(a1).map(|(lhs, rhs)| lhs * rhs);
+///
+/// // `Simd<T, N>` implements `From<[T; N]>
+/// let (v0, v1) = (Simd::from(a0), Simd::from(a1));
+/// // Which means arrays implement `Into<Simd<T, N>>`.
+/// assert_eq!(v0 + v1, zm_add.into());
+/// assert_eq!(v0 * v1, zm_mul.into());
+/// ```
+///
+/// `Simd` with integers has the quirk that these operations are also inherently wrapping, as if `T` was [`Wrapping<T>`].
+/// Thus, `Simd` does not implement `wrapping_add`, because that is the default behavior.
+/// This means there is no warning on overflows, even in "debug" builds.
+/// For most applications where `Simd` is appropriate, it is "not a bug" to wrap,
+/// and even "debug builds" are unlikely to tolerate the loss of performance.
+/// You may want to consider using explicitly checked arithmetic if such is required.
+/// Division by zero still causes a panic, so you may want to consider using floating point numbers if that is unacceptable.
+///
+/// [`Wrapping<T>`]: core::num::Wrapping
+///
+/// # Layout
+/// `Simd<T, N>` has a layout similar to `[T; N]` (identical "shapes"), but with a greater alignment.
+/// `[T; N]` is aligned to `T`, but `Simd<T, N>` will have an alignment based on both `T` and `N`.
+/// It is thus sound to [`transmute`] `Simd<T, N>` to `[T; N]`, and will typically optimize to zero cost,
+/// but the reverse transmutation is more likely to require a copy the compiler cannot simply elide.
+///
+/// # ABI "Features"
+/// Due to Rust's safety guarantees, `Simd<T, N>` is currently passed to and from functions via memory, not SIMD registers,
+/// except as an optimization. `#[inline]` hints are recommended on functions that accept `Simd<T, N>` or return it.
+/// The need for this may be corrected in the future.
+///
+/// # Safe SIMD with Unsafe Rust
+///
+/// Operations with `Simd` are typically safe, but there are many reasons to want to combine SIMD with `unsafe` code.
+/// Care must be taken to respect differences between `Simd` and other types it may be transformed into or derived from.
+/// In particular, the layout of `Simd<T, N>` may be similar to `[T; N]`, and may allow some transmutations,
+/// but references to `[T; N]` are not interchangeable with those to `Simd<T, N>`.
+/// Thus, when using `unsafe` Rust to read and write `Simd<T, N>` through [raw pointers], it is a good idea to first try with
+/// [`read_unaligned`] and [`write_unaligned`]. This is because:
+/// - [`read`] and [`write`] require full alignment (in this case, `Simd<T, N>`'s alignment)
+/// - the likely source for reading or destination for writing `Simd<T, N>` is [`[T]`](slice) and similar types, aligned to `T`
+/// - combining these actions would violate the `unsafe` contract and explode the program into a puff of **undefined behavior**
+/// - the compiler can implicitly adjust layouts to make unaligned reads or writes fully aligned if it sees the optimization
+/// - most contemporary processors suffer no performance penalty for "unaligned" reads and writes that are aligned at runtime
+///
+/// By imposing less obligations, unaligned functions are less likely to make the program unsound,
+/// and may be just as fast as stricter alternatives.
+/// When trying to guarantee alignment, [`[T]::as_simd`][as_simd] is an option for converting `[T]` to `[Simd<T, N>]`,
+/// and allows soundly operating on an aligned SIMD body, but it may cost more time when handling the scalar head and tail.
+/// If these are not sufficient, then it is most ideal to design data structures to be already aligned
+/// to the `Simd<T, N>` you wish to use before using `unsafe` Rust to read or write.
+/// More conventional ways to compensate for these facts, like materializing `Simd` to or from an array first,
+/// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`].
+///
+/// [`transmute`]: core::mem::transmute
+/// [raw pointers]: pointer
+/// [`read_unaligned`]: pointer::read_unaligned
+/// [`write_unaligned`]: pointer::write_unaligned
+/// [`read`]: pointer::read
+/// [`write`]: pointer::write
+/// [as_simd]: slice::as_simd
 #[repr(simd)]
 pub struct Simd<T, const LANES: usize>([T; LANES])
 where
@@ -98,6 +170,7 @@ where
     #[must_use]
     #[inline]
     pub fn cast<U: SimdElement>(self) -> Simd<U, LANES> {
+        // Safety: The input argument is a vector of a known SIMD type.
         unsafe { intrinsics::simd_as(self) }
     }
 
@@ -171,7 +244,7 @@ where
         or: Self,
     ) -> Self {
         let enable: Mask<isize, LANES> = enable & idxs.lanes_lt(Simd::splat(slice.len()));
-        // SAFETY: We have masked-off out-of-bounds lanes.
+        // Safety: We have masked-off out-of-bounds lanes.
         unsafe { Self::gather_select_unchecked(slice, enable, idxs, or) }
     }
 
@@ -212,7 +285,7 @@ where
         let base_ptr = crate::simd::ptr::SimdConstPtr::splat(slice.as_ptr());
         // Ferris forgive me, I have done pointer arithmetic here.
         let ptrs = base_ptr.wrapping_add(idxs);
-        // SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
+        // Safety: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
         unsafe { intrinsics::simd_gather(or, ptrs, enable.to_int()) }
     }
 
@@ -264,7 +337,7 @@ where
         idxs: Simd<usize, LANES>,
     ) {
         let enable: Mask<isize, LANES> = enable & idxs.lanes_lt(Simd::splat(slice.len()));
-        // SAFETY: We have masked-off out-of-bounds lanes.
+        // Safety: We have masked-off out-of-bounds lanes.
         unsafe { self.scatter_select_unchecked(slice, enable, idxs) }
     }
 
@@ -303,7 +376,7 @@ where
         enable: Mask<isize, LANES>,
         idxs: Simd<usize, LANES>,
     ) {
-        // SAFETY: This block works with *mut T derived from &mut 'a [T],
+        // Safety: This block works with *mut T derived from &mut 'a [T],
         // which means it is delicate in Rust's borrowing model, circa 2021:
         // &mut 'a [T] asserts uniqueness, so deriving &'a [T] invalidates live *mut Ts!
         // Even though this block is largely safe methods, it must be exactly this way
@@ -483,7 +556,9 @@ mod sealed {
 use sealed::Sealed;
 
 /// Marker trait for types that may be used as SIMD vector elements.
-/// SAFETY: This trait, when implemented, asserts the compiler can monomorphize
+///
+/// # Safety
+/// This trait, when implemented, asserts the compiler can monomorphize
 /// `#[repr(simd)]` structs with the marked type as an element.
 /// Strictly, it is valid to impl if the vector will not be miscompiled.
 /// Practically, it is user-unfriendly to impl it if the vector won't compile,
diff --git a/library/portable-simd/crates/core_simd/src/vector/ptr.rs b/library/portable-simd/crates/core_simd/src/vector/ptr.rs
index c668d9a6eae..417d255c28d 100644
--- a/library/portable-simd/crates/core_simd/src/vector/ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/vector/ptr.rs
@@ -21,6 +21,8 @@ where
     #[inline]
     #[must_use]
     pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
+        // Safety: converting pointers to usize and vice-versa is safe
+        // (even if using that pointer is not)
         unsafe {
             let x: Simd<usize, LANES> = mem::transmute_copy(&self);
             mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
@@ -47,6 +49,8 @@ where
     #[inline]
     #[must_use]
     pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
+        // Safety: converting pointers to usize and vice-versa is safe
+        // (even if using that pointer is not)
         unsafe {
             let x: Simd<usize, LANES> = mem::transmute_copy(&self);
             mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
diff --git a/library/portable-simd/crates/core_simd/src/vendor.rs b/library/portable-simd/crates/core_simd/src/vendor.rs
index e8ce7176b4f..9fb70218c95 100644
--- a/library/portable-simd/crates/core_simd/src/vendor.rs
+++ b/library/portable-simd/crates/core_simd/src/vendor.rs
@@ -9,6 +9,8 @@ macro_rules! from_transmute {
         impl core::convert::From<$from> for $to {
             #[inline]
             fn from(value: $from) -> $to {
+                // Safety: transmuting between vectors is safe, but the caller of this macro
+                // checks the invariants
                 unsafe { core::mem::transmute(value) }
             }
         }
diff --git a/library/portable-simd/crates/core_simd/tests/masks.rs b/library/portable-simd/crates/core_simd/tests/masks.rs
index 6a8ecd33a73..3aec36ca7b7 100644
--- a/library/portable-simd/crates/core_simd/tests/masks.rs
+++ b/library/portable-simd/crates/core_simd/tests/masks.rs
@@ -68,16 +68,16 @@ macro_rules! test_mask_api {
                 assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
             }
 
-            #[cfg(feature = "generic_const_exprs")]
             #[test]
             fn roundtrip_bitmask_conversion() {
+                use core_simd::ToBitMask;
                 let values = [
                     true, false, false, true, false, false, true, false,
                     true, true, false, false, false, false, false, true,
                 ];
                 let mask = core_simd::Mask::<$type, 16>::from_array(values);
                 let bitmask = mask.to_bitmask();
-                assert_eq!(bitmask, [0b01001001, 0b10000011]);
+                assert_eq!(bitmask, 0b1000001101001001);
                 assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
             }
         }
diff --git a/library/portable-simd/crates/core_simd/tests/ops_macros.rs b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
index 4fb9de198ee..50f7a4ca170 100644
--- a/library/portable-simd/crates/core_simd/tests/ops_macros.rs
+++ b/library/portable-simd/crates/core_simd/tests/ops_macros.rs
@@ -210,15 +210,21 @@ macro_rules! impl_signed_tests {
                     )
                 }
 
-            }
+                fn div_min_may_overflow<const LANES: usize>() {
+                    let a = Vector::<LANES>::splat(Scalar::MIN);
+                    let b = Vector::<LANES>::splat(-1);
+                    assert_eq!(a / b, a);
+                }
 
-            test_helpers::test_lanes_panic! {
-                fn div_min_overflow_panics<const LANES: usize>() {
+                fn rem_min_may_overflow<const LANES: usize>() {
                     let a = Vector::<LANES>::splat(Scalar::MIN);
                     let b = Vector::<LANES>::splat(-1);
-                    let _ = a / b;
+                    assert_eq!(a % b, Vector::<LANES>::splat(0));
                 }
 
+            }
+
+            test_helpers::test_lanes_panic! {
                 fn div_by_all_zeros_panics<const LANES: usize>() {
                     let a = Vector::<LANES>::splat(42);
                     let b = Vector::<LANES>::splat(0);
@@ -232,12 +238,6 @@ macro_rules! impl_signed_tests {
                     let _ = a / b;
                 }
 
-                fn rem_min_overflow_panic<const LANES: usize>() {
-                    let a = Vector::<LANES>::splat(Scalar::MIN);
-                    let b = Vector::<LANES>::splat(-1);
-                    let _ = a % b;
-                }
-
                 fn rem_zero_panic<const LANES: usize>() {
                     let a = Vector::<LANES>::splat(42);
                     let b = Vector::<LANES>::splat(0);
diff --git a/library/portable-simd/crates/core_simd/tests/round.rs b/library/portable-simd/crates/core_simd/tests/round.rs
index 1a1bc9ebca7..53732329237 100644
--- a/library/portable-simd/crates/core_simd/tests/round.rs
+++ b/library/portable-simd/crates/core_simd/tests/round.rs
@@ -53,14 +53,6 @@ macro_rules! float_rounding_test {
             }
 
             test_helpers::test_lanes! {
-                fn from_int<const LANES: usize>() {
-                    test_helpers::test_unary_elementwise(
-                        &Vector::<LANES>::round_from_int,
-                        &|x| x as Scalar,
-                        &|_| true,
-                    )
-                }
-
                 fn to_int_unchecked<const LANES: usize>() {
                     // The maximum integer that can be represented by the equivalently sized float has
                     // all of the mantissa digits set to 1, pushed up to the MSB.
@@ -72,11 +64,11 @@ macro_rules! float_rounding_test {
                     runner.run(
                         &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE),
                         |x| {
-                            let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() };
+                            let result_1 = unsafe { Vector::from_array(x).to_int_unchecked::<IntScalar>().to_array() };
                             let result_2 = {
-                                let mut result = [0; LANES];
+                                let mut result: [IntScalar; LANES] = [0; LANES];
                                 for (i, o) in x.iter().zip(result.iter_mut()) {
-                                    *o = unsafe { i.to_int_unchecked() };
+                                    *o = unsafe { i.to_int_unchecked::<IntScalar>() };
                                 }
                                 result
                             };
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index aa6400aeefa..5de12313784 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -407,11 +407,11 @@ impl Socket {
     }
 
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
-        net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
+        net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL)
     }
 
     pub fn nodelay(&self) -> io::Result<bool> {
-        let raw: c::BYTE = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
+        let raw: c::BOOL = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
         Ok(raw != 0)
     }
 
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 70b29d4a92e..3b7cdd55a08 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -58,21 +58,36 @@ cfg_if::cfg_if! {
 // sockaddr and misc bindings
 ////////////////////////////////////////////////////////////////////////////////
 
-pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int, payload: T) -> io::Result<()> {
+pub fn setsockopt<T>(
+    sock: &Socket,
+    level: c_int,
+    option_name: c_int,
+    option_value: T,
+) -> io::Result<()> {
     unsafe {
-        let payload = &payload as *const T as *const c_void;
-        cvt(c::setsockopt(sock.as_raw(), opt, val, payload, mem::size_of::<T>() as c::socklen_t))?;
+        cvt(c::setsockopt(
+            sock.as_raw(),
+            level,
+            option_name,
+            &option_value as *const T as *const _,
+            mem::size_of::<T>() as c::socklen_t,
+        ))?;
         Ok(())
     }
 }
 
-pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int, val: c_int) -> io::Result<T> {
+pub fn getsockopt<T: Copy>(sock: &Socket, level: c_int, option_name: c_int) -> io::Result<T> {
     unsafe {
-        let mut slot: T = mem::zeroed();
-        let mut len = mem::size_of::<T>() as c::socklen_t;
-        cvt(c::getsockopt(sock.as_raw(), opt, val, &mut slot as *mut _ as *mut _, &mut len))?;
-        assert_eq!(len as usize, mem::size_of::<T>());
-        Ok(slot)
+        let mut option_value: T = mem::zeroed();
+        let mut option_len = mem::size_of::<T>() as c::socklen_t;
+        cvt(c::getsockopt(
+            sock.as_raw(),
+            level,
+            option_name,
+            &mut option_value as *mut T as *mut _,
+            &mut option_len,
+        ))?;
+        Ok(option_value)
     }
 }
 
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 75ee663b926..6f4b87750ff 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -101,27 +101,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
 
                     cx.generated_synthetics.insert((ty, trait_def_id));
 
-                    let hir_imp = impl_def_id.as_local()
-                        .map(|local| cx.tcx.hir().expect_item(local))
-                        .and_then(|item| if let hir::ItemKind::Impl(i) = &item.kind {
-                            Some(i)
-                        } else {
-                            None
-                        });
-
-                    let items = match hir_imp {
-                        Some(imp) => imp
-                            .items
-                            .iter()
-                            .map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx))
-                            .collect::<Vec<_>>(),
-                        None => cx.tcx
-                            .associated_items(impl_def_id)
-                            .in_definition_order()
-                            .map(|x| x.clean(cx))
-                            .collect::<Vec<_>>(),
-                    };
-
                     impls.push(Item {
                         name: None,
                         attrs: Default::default(),
@@ -138,7 +117,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             // the post-inference `trait_ref`, as it's more accurate.
                             trait_: Some(trait_ref.clean(cx)),
                             for_: ty.clean(cx),
-                            items,
+                            items: cx.tcx
+                                .associated_items(impl_def_id)
+                                .in_definition_order()
+                                .map(|x| x.clean(cx))
+                                .collect::<Vec<_>>(),
                             polarity: ty::ImplPolarity::Positive,
                             kind: ImplKind::Blanket(box trait_ref.self_ty().clean(cx)),
                         }),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index f0ae01f3803..3ae1df51695 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -228,7 +228,7 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi
     let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
         // NOTE: generics need to be cleaned before the decl!
         let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates);
-        let decl = clean_fn_decl_from_did_and_sig(cx, did, sig);
+        let decl = clean_fn_decl_from_did_and_sig(cx, Some(did), sig);
         (generics, decl)
     });
     clean::Function {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e0e641c2f9b..8fad625973f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -891,13 +891,20 @@ fn clean_fn_decl_with_args(
 
 fn clean_fn_decl_from_did_and_sig(
     cx: &mut DocContext<'_>,
-    did: DefId,
+    did: Option<DefId>,
     sig: ty::PolyFnSig<'_>,
 ) -> FnDecl {
-    let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter();
+    let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_names(did)).iter();
+
+    // We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
+    // but shouldn't change any code meaning.
+    let output = match sig.skip_binder().output().clean(cx) {
+        Type::Tuple(inner) if inner.len() == 0 => DefaultReturn,
+        ty => Return(ty),
+    };
 
     FnDecl {
-        output: Return(sig.skip_binder().output().clean(cx)),
+        output,
         c_variadic: sig.skip_binder().c_variadic,
         inputs: Arguments {
             values: sig
@@ -1031,20 +1038,18 @@ impl Clean<Item> for hir::ImplItem<'_> {
                 }
             };
 
-            let what_rustc_thinks =
+            let mut what_rustc_thinks =
                 Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx);
-            let parent_item = cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(self.hir_id()));
-            if let hir::ItemKind::Impl(impl_) = &parent_item.kind {
-                if impl_.of_trait.is_some() {
-                    // Trait impl items always inherit the impl's visibility --
-                    // we don't want to show `pub`.
-                    Item { visibility: Inherited, ..what_rustc_thinks }
-                } else {
-                    what_rustc_thinks
-                }
-            } else {
-                panic!("found impl item with non-impl parent {:?}", parent_item);
+
+            let impl_ref = cx.tcx.parent(local_did).and_then(|did| cx.tcx.impl_trait_ref(did));
+
+            // Trait impl items always inherit the impl's visibility --
+            // we don't want to show `pub`.
+            if impl_ref.is_some() {
+                what_rustc_thinks.visibility = Inherited;
             }
+
+            what_rustc_thinks
         })
     }
 }
@@ -1069,7 +1074,7 @@ impl Clean<Item> for ty::AssocItem {
                     tcx.explicit_predicates_of(self.def_id),
                 );
                 let sig = tcx.fn_sig(self.def_id);
-                let mut decl = clean_fn_decl_from_did_and_sig(cx, self.def_id, sig);
+                let mut decl = clean_fn_decl_from_did_and_sig(cx, Some(self.def_id), sig);
 
                 if self.fn_has_self_parameter {
                     let self_ty = match self.container {
@@ -1199,7 +1204,18 @@ impl Clean<Item> for ty::AssocItem {
             }
         };
 
-        Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx)
+        let mut what_rustc_thinks =
+            Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx);
+
+        let impl_ref = tcx.parent(self.def_id).and_then(|did| tcx.impl_trait_ref(did));
+
+        // Trait impl items always inherit the impl's visibility --
+        // we don't want to show `pub`.
+        if impl_ref.is_some() {
+            what_rustc_thinks.visibility = Visibility::Inherited;
+        }
+
+        what_rustc_thinks
     }
 }
 
@@ -1478,8 +1494,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
             ty::FnDef(..) | ty::FnPtr(_) => {
                 let ty = cx.tcx.lift(*self).expect("FnPtr lift failed");
                 let sig = ty.fn_sig(cx.tcx);
-                let def_id = DefId::local(CRATE_DEF_INDEX);
-                let decl = clean_fn_decl_from_did_and_sig(cx, def_id, sig);
+                let decl = clean_fn_decl_from_did_and_sig(cx, None, sig);
                 BareFunction(box BareFunctionDecl {
                     unsafety: sig.unsafety(),
                     generic_params: Vec::new(),
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index ed382406efa..b0e295178c8 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -71,6 +71,7 @@
 //~^^ WARN this was previously accepted by the compiler
 // see issue-43106-gating-of-rustc_deprecated.rs
 #![must_use]
+//~^ WARN `#[must_use]` has no effect
 // see issue-43106-gating-of-stable.rs
 // see issue-43106-gating-of-unstable.rs
 // see issue-43106-gating-of-deprecated.rs
@@ -597,17 +598,17 @@ mod deprecated {
     #[deprecated] impl super::StructForDeprecated { }
 }
 
-#[must_use]
+#[must_use] //~ WARN `#[must_use]` has no effect
 mod must_use {
-    mod inner { #![must_use] }
+    mod inner { #![must_use] } //~ WARN `#[must_use]` has no effect
 
     #[must_use] fn f() { }
 
     #[must_use] struct S;
 
-    #[must_use] type T = S;
+    #[must_use] type T = S; //~ WARN `#[must_use]` has no effect
 
-    #[must_use] impl S { }
+    #[must_use] impl S { } //~ WARN `#[must_use]` has no effect
 }
 
 #[windows_subsystem = "windows"]
diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index bd3e33320c3..2431957e539 100644
--- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -29,151 +29,151 @@ LL | #![deny(x5100)]
    |         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:105:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:106:8
    |
 LL | #[warn(x5400)]
    |        ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:108:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:109:25
    |
 LL |     mod inner { #![warn(x5400)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:111:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:12
    |
 LL |     #[warn(x5400)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:12
    |
 LL |     #[warn(x5400)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:12
    |
 LL |     #[warn(x5400)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:12
    |
 LL |     #[warn(x5400)] impl S { }
    |            ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:9
    |
 LL | #[allow(x5300)]
    |         ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:26
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:26
    |
 LL |     mod inner { #![allow(x5300)] }
    |                          ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:130:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:13
    |
 LL |     #[allow(x5300)] fn f() { }
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:13
    |
 LL |     #[allow(x5300)] struct S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:13
    |
 LL |     #[allow(x5300)] type T = S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:13
    |
 LL |     #[allow(x5300)] impl S { }
    |             ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:10
    |
 LL | #[forbid(x5200)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:27
    |
 LL |     mod inner { #![forbid(x5200)] }
    |                           ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:149:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:14
    |
 LL |     #[forbid(x5200)] fn f() { }
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:14
    |
 LL |     #[forbid(x5200)] struct S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:14
    |
 LL |     #[forbid(x5200)] type T = S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:14
    |
 LL |     #[forbid(x5200)] impl S { }
    |              ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:8
    |
 LL | #[deny(x5100)]
    |        ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:25
    |
 LL |     mod inner { #![deny(x5100)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:168:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:12
    |
 LL |     #[deny(x5100)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:12
    |
 LL |     #[deny(x5100)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:175:12
    |
 LL |     #[deny(x5100)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:178:12
    |
 LL |     #[deny(x5100)] impl S { }
    |            ^^^^^
 
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:17
    |
 LL |     mod inner { #![macro_escape] }
    |                 ^^^^^^^^^^^^^^^^
@@ -181,13 +181,13 @@ LL |     mod inner { #![macro_escape] }
    = help: try an outer attribute: `#[macro_use]`
 
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:1
    |
 LL | #[macro_escape]
    | ^^^^^^^^^^^^^^^
 
 warning: use of deprecated attribute `crate_id`: no longer used.
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:84:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:85:1
    |
 LL | #![crate_id = "10"]
    | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
@@ -195,13 +195,13 @@ LL | #![crate_id = "10"]
    = note: `#[warn(deprecated)]` on by default
 
 warning: use of deprecated attribute `no_start`: no longer used.
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:95:1
    |
 LL | #![no_start]
    | ^^^^^^^^^^^^ help: remove this attribute
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:1
    |
 LL | #[macro_export]
    | ^^^^^^^^^^^^^^^
@@ -213,13 +213,13 @@ LL | #![warn(unused_attributes, unknown_lints)]
    |         ^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on items
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:267:1
    |
 LL | #[automatically_derived]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:284:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:285:1
    |
 LL |   #[no_mangle]
    |   ^^^^^^^^^^^^
@@ -236,31 +236,31 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:1
    |
 LL | #[should_panic]
    | ^^^^^^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:1
    |
 LL | #[ignore]
    | ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:1
    |
 LL | #[reexport_test_harness_main = "2900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1
    |
 LL | #[no_std]
    | ^^^^^^^^^
 
 warning: attribute should be applied to a function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:453:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:1
    |
 LL |   #[cold]
    |   ^^^^^^^
@@ -277,7 +277,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:1
    |
 LL |   #[link_name = "1900"]
    |   ^^^^^^^^^^^^^^^^^^^^^
@@ -294,7 +294,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:521:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:522:1
    |
 LL |   #[link_section = "1800"]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:553:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:554:1
    |
 LL |   #[link()]
    |   ^^^^^^^^^
@@ -327,50 +327,56 @@ LL | | }
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
+warning: `#[must_use]` has no effect when applied to a module
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:601:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:613:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:1
    |
 LL | #[windows_subsystem = "windows"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:634:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:653:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:1
    |
 LL | #[no_main]
    | ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1
    |
 LL | #[no_builtins]
    | ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:730:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:749:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -425,110 +431,116 @@ LL | #![link_section = "1800"]
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
+warning: `#[must_use]` has no effect when applied to a module
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:73:1
+   |
+LL | #![must_use]
+   | ^^^^^^^^^^^^
+
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:5
    |
 LL |     #[macro_use] fn f() { }
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:188:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:5
    |
 LL |     #[macro_use] struct S;
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5
    |
 LL |     #[macro_use] type T = S;
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
    |
 LL |     #[macro_use] impl S { }
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:202:17
    |
 LL |     mod inner { #![macro_export] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:5
    |
 LL |     #[macro_export] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:5
    |
 LL |     #[macro_export] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:211:5
    |
 LL |     #[macro_export] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:5
    |
 LL |     #[macro_export] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:254:5
    |
 LL |     #[path = "3800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:5
    |
 LL |     #[path = "3800"]  struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:259:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:5
    |
 LL |     #[path = "3800"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:5
    |
 LL |     #[path = "3800"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on items
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:17
    |
 LL |     mod inner { #![automatically_derived] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on items
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
    |
 LL |     #[automatically_derived] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on items
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
    |
 LL |     #[automatically_derived] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on items
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:278:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:279:5
    |
 LL |     #[automatically_derived] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:289:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:290:17
    |
 LL |     mod inner { #![no_mangle] }
    |     ------------^^^^^^^^^^^^^-- not a free function, impl method or static
@@ -536,7 +548,7 @@ LL |     mod inner { #![no_mangle] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:296:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:297:5
    |
 LL |     #[no_mangle] struct S;
    |     ^^^^^^^^^^^^ --------- not a free function, impl method or static
@@ -544,7 +556,7 @@ LL |     #[no_mangle] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:301:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:302:5
    |
 LL |     #[no_mangle] type T = S;
    |     ^^^^^^^^^^^^ ----------- not a free function, impl method or static
@@ -552,7 +564,7 @@ LL |     #[no_mangle] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:306:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:307:5
    |
 LL |     #[no_mangle] impl S { }
    |     ^^^^^^^^^^^^ ---------- not a free function, impl method or static
@@ -560,7 +572,7 @@ LL |     #[no_mangle] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:9
    |
 LL |         #[no_mangle] fn foo();
    |         ^^^^^^^^^^^^ --------- not a free function, impl method or static
@@ -568,7 +580,7 @@ LL |         #[no_mangle] fn foo();
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:317:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:318:9
    |
 LL |         #[no_mangle] fn bar() {}
    |         ^^^^^^^^^^^^ ----------- not a free function, impl method or static
@@ -576,163 +588,163 @@ LL |         #[no_mangle] fn bar() {}
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:327:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:17
    |
 LL |     mod inner { #![should_panic] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:5
    |
 LL |     #[should_panic] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:5
    |
 LL |     #[should_panic] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:5
    |
 LL |     #[should_panic] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:346:17
    |
 LL |     mod inner { #![ignore] }
    |                 ^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
    |
 LL |     #[ignore] struct S;
    |     ^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5
    |
 LL |     #[ignore] type T = S;
    |     ^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:356:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:357:5
    |
 LL |     #[ignore] impl S { }
    |     ^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:5
    |
 LL |     #[no_implicit_prelude] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:5
    |
 LL |     #[no_implicit_prelude] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
    |
 LL |     #[no_implicit_prelude] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:5
    |
 LL |     #[no_implicit_prelude] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:381:17
    |
 LL |     mod inner { #![reexport_test_harness_main="2900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:5
    |
 LL |     #[reexport_test_harness_main = "2900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:5
    |
 LL |     #[reexport_test_harness_main = "2900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
    |
 LL |     #[reexport_test_harness_main = "2900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:393:5
    |
 LL |     #[reexport_test_harness_main = "2900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:5
    |
 LL |     #[macro_escape] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5
    |
 LL |     #[macro_escape] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5
    |
 LL |     #[macro_escape] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5
    |
 LL |     #[macro_escape] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:17
    |
 LL |     mod inner { #![no_std] }
    |                 ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:5
    |
 LL |     #[no_std] fn f() { }
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5
    |
 LL |     #[no_std] struct S;
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5
    |
 LL |     #[no_std] type T = S;
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5
    |
 LL |     #[no_std] impl S { }
    |     ^^^^^^^^^
 
 warning: attribute should be applied to a function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:17
    |
 LL |     mod inner { #![cold] }
    |     ------------^^^^^^^^-- not a function
@@ -740,7 +752,7 @@ LL |     mod inner { #![cold] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
    |
 LL |     #[cold] struct S;
    |     ^^^^^^^ --------- not a function
@@ -748,7 +760,7 @@ LL |     #[cold] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:5
    |
 LL |     #[cold] type T = S;
    |     ^^^^^^^ ----------- not a function
@@ -756,7 +768,7 @@ LL |     #[cold] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:5
    |
 LL |     #[cold] impl S { }
    |     ^^^^^^^ ---------- not a function
@@ -764,7 +776,7 @@ LL |     #[cold] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -774,13 +786,13 @@ LL |     extern "C" { }
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 help: try `#[link(name = "1900")]` instead
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
    |
 LL |     mod inner { #![link_name="1900"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^-- not a foreign function or static
@@ -788,7 +800,7 @@ LL |     mod inner { #![link_name="1900"] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:5
    |
 LL |     #[link_name = "1900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -796,7 +808,7 @@ LL |     #[link_name = "1900"] fn f() { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:5
    |
 LL |     #[link_name = "1900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^ --------- not a foreign function or static
@@ -804,7 +816,7 @@ LL |     #[link_name = "1900"] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:510:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:511:5
    |
 LL |     #[link_name = "1900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^ ----------- not a foreign function or static
@@ -812,7 +824,7 @@ LL |     #[link_name = "1900"] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:515:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:5
    |
 LL |     #[link_name = "1900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -820,7 +832,7 @@ LL |     #[link_name = "1900"] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:17
    |
 LL |     mod inner { #![link_section="1800"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^^^^-- not a function or static
@@ -828,7 +840,7 @@ LL |     mod inner { #![link_section="1800"] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:534:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5
    |
 LL |     #[link_section = "1800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static
@@ -836,7 +848,7 @@ LL |     #[link_section = "1800"] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:539:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:5
    |
 LL |     #[link_section = "1800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static
@@ -844,7 +856,7 @@ LL |     #[link_section = "1800"] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:545:5
    |
 LL |     #[link_section = "1800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
@@ -852,7 +864,7 @@ LL |     #[link_section = "1800"] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:560:17
    |
 LL |     mod inner { #![link()] }
    |     ------------^^^^^^^^^^-- not an `extern` block
@@ -860,7 +872,7 @@ LL |     mod inner { #![link()] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:564:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:565:5
    |
 LL |     #[link()] fn f() { }
    |     ^^^^^^^^^ ---------- not an `extern` block
@@ -868,7 +880,7 @@ LL |     #[link()] fn f() { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:569:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:570:5
    |
 LL |     #[link()] struct S;
    |     ^^^^^^^^^ --------- not an `extern` block
@@ -876,7 +888,7 @@ LL |     #[link()] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:574:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:575:5
    |
 LL |     #[link()] type T = S;
    |     ^^^^^^^^^ ----------- not an `extern` block
@@ -884,260 +896,278 @@ LL |     #[link()] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:579:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:580:5
    |
 LL |     #[link()] impl S { }
    |     ^^^^^^^^^ ---------- not an `extern` block
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
+warning: `#[must_use]` has no effect when applied to a module
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:603:17
+   |
+LL |     mod inner { #![must_use] }
+   |                 ^^^^^^^^^^^^
+
+warning: `#[must_use]` has no effect when applied to a type alias
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:609:5
+   |
+LL |     #[must_use] type T = S;
+   |     ^^^^^^^^^^^
+
+warning: `#[must_use]` has no effect when applied to an item
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:611:5
+   |
+LL |     #[must_use] impl S { }
+   |     ^^^^^^^^^^^
+
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:616:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:617:17
    |
 LL |     mod inner { #![windows_subsystem="windows"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:619:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:620:5
    |
 LL |     #[windows_subsystem = "windows"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:622:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:623:5
    |
 LL |     #[windows_subsystem = "windows"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:625:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:626:5
    |
 LL |     #[windows_subsystem = "windows"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:628:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:629:5
    |
 LL |     #[windows_subsystem = "windows"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:637:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:640:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:641:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:646:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:649:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:650:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:656:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:662:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:665:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
    |
 LL |     mod inner { #![no_main] }
    |                 ^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:698:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5
    |
 LL |     #[no_main] fn f() { }
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5
    |
 LL |     #[no_main] struct S;
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5
    |
 LL |     #[no_main] type T = S;
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
    |
 LL |     #[no_main] impl S { }
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:714:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:17
    |
 LL |     mod inner { #![no_builtins] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5
    |
 LL |     #[no_builtins] fn f() { }
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
    |
 LL |     #[no_builtins] struct S;
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5
    |
 LL |     #[no_builtins] type T = S;
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
    |
 LL |     #[no_builtins] impl S { }
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:752:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:91:12
    |
 LL | #![feature(rust1)]
    |            ^^^^^
    |
    = note: `#[warn(stable_features)]` on by default
 
-warning: 167 warnings emitted
+warning: 172 warnings emitted
 
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.rs b/src/test/ui/lint/unused/unused_attributes-must_use.rs
new file mode 100644
index 00000000000..1c4abb9491e
--- /dev/null
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.rs
@@ -0,0 +1,125 @@
+#![allow(dead_code, path_statements)]
+#![deny(unused_attributes, unused_must_use)]
+#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+extern crate std as std2;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+mod test_mod {}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+use std::arch::global_asm;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+const CONST: usize = 4;
+#[must_use] //~ ERROR `#[must_use]` has no effect
+#[no_mangle]
+static STATIC: usize = 4;
+
+#[must_use]
+struct X;
+
+#[must_use]
+enum Y {
+    Z,
+}
+
+#[must_use]
+union U {
+    unit: (),
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+impl U {
+    #[must_use]
+    fn method() -> i32 {
+        4
+    }
+}
+
+#[must_use]
+#[no_mangle]
+fn foo() -> i64 {
+    4
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+extern "Rust" {
+    #[link_name = "STATIC"]
+    #[must_use] //~ ERROR `#[must_use]` has no effect
+    static FOREIGN_STATIC: usize;
+
+    #[link_name = "foo"]
+    #[must_use]
+    fn foreign_foo() -> i64;
+}
+
+#[must_use] //~ ERROR unused attribute
+global_asm!("");
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+type UseMe = ();
+
+fn qux<#[must_use] T>(_: T) {} //~ ERROR `#[must_use]` has no effect
+
+#[must_use]
+trait Use {
+    #[must_use] //~ ERROR `#[must_use]` has no effect
+    const ASSOC_CONST: usize = 4;
+    #[must_use] //~ ERROR `#[must_use]` has no effect
+    type AssocTy;
+
+    #[must_use]
+    fn get_four(&self) -> usize {
+        4
+    }
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+impl Use for () {
+    type AssocTy = ();
+}
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+trait Alias = Use;
+
+#[must_use] //~ ERROR `#[must_use]` has no effect
+macro_rules! cool_macro {
+    () => {
+        4
+    };
+}
+
+fn main() {
+    #[must_use] //~ ERROR `#[must_use]` has no effect
+    let x = || {};
+    x();
+
+    let x = #[must_use] //~ ERROR `#[must_use]` has no effect
+    || {};
+    x();
+
+    X; //~ ERROR that must be used
+    Y::Z; //~ ERROR that must be used
+    U { unit: () }; //~ ERROR that must be used
+    U::method(); //~ ERROR that must be used
+    foo(); //~ ERROR that must be used
+
+    unsafe {
+        foreign_foo(); //~ ERROR that must be used
+    };
+
+    CONST;
+    STATIC;
+    unsafe { FOREIGN_STATIC };
+    cool_macro!();
+    qux(4);
+    ().get_four(); //~ ERROR that must be used
+
+    match Some(4) {
+        #[must_use] //~ ERROR `#[must_use]` has no effect
+        Some(res) => res,
+        None => 0,
+    };
+}
diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
new file mode 100644
index 00000000000..27269580e52
--- /dev/null
+++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr
@@ -0,0 +1,175 @@
+error: unused attribute `must_use`
+  --> $DIR/unused_attributes-must_use.rs:58:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused_attributes-must_use.rs:2:9
+   |
+LL | #![deny(unused_attributes, unused_must_use)]
+   |         ^^^^^^^^^^^^^^^^^
+note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
+  --> $DIR/unused_attributes-must_use.rs:59:1
+   |
+LL | global_asm!("");
+   | ^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an extern crate
+  --> $DIR/unused_attributes-must_use.rs:5:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a module
+  --> $DIR/unused_attributes-must_use.rs:8:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a use
+  --> $DIR/unused_attributes-must_use.rs:11:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a constant item
+  --> $DIR/unused_attributes-must_use.rs:14:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a static item
+  --> $DIR/unused_attributes-must_use.rs:16:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an item
+  --> $DIR/unused_attributes-must_use.rs:33:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a foreign module
+  --> $DIR/unused_attributes-must_use.rs:47:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a type alias
+  --> $DIR/unused_attributes-must_use.rs:61:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a type parameter
+  --> $DIR/unused_attributes-must_use.rs:64:8
+   |
+LL | fn qux<#[must_use] T>(_: T) {}
+   |        ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an item
+  --> $DIR/unused_attributes-must_use.rs:79:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a trait alias
+  --> $DIR/unused_attributes-must_use.rs:84:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a macro def
+  --> $DIR/unused_attributes-must_use.rs:87:1
+   |
+LL | #[must_use]
+   | ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a statement
+  --> $DIR/unused_attributes-must_use.rs:95:5
+   |
+LL |     #[must_use]
+   |     ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a closure
+  --> $DIR/unused_attributes-must_use.rs:99:13
+   |
+LL |     let x = #[must_use]
+   |             ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an match arm
+  --> $DIR/unused_attributes-must_use.rs:121:9
+   |
+LL |         #[must_use]
+   |         ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an associated const
+  --> $DIR/unused_attributes-must_use.rs:68:5
+   |
+LL |     #[must_use]
+   |     ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to an associated type
+  --> $DIR/unused_attributes-must_use.rs:70:5
+   |
+LL |     #[must_use]
+   |     ^^^^^^^^^^^
+
+error: `#[must_use]` has no effect when applied to a foreign static item
+  --> $DIR/unused_attributes-must_use.rs:50:5
+   |
+LL |     #[must_use]
+   |     ^^^^^^^^^^^
+
+error: unused `X` that must be used
+  --> $DIR/unused_attributes-must_use.rs:103:5
+   |
+LL |     X;
+   |     ^^
+   |
+note: the lint level is defined here
+  --> $DIR/unused_attributes-must_use.rs:2:28
+   |
+LL | #![deny(unused_attributes, unused_must_use)]
+   |                            ^^^^^^^^^^^^^^^
+
+error: unused `Y` that must be used
+  --> $DIR/unused_attributes-must_use.rs:104:5
+   |
+LL |     Y::Z;
+   |     ^^^^^
+
+error: unused `U` that must be used
+  --> $DIR/unused_attributes-must_use.rs:105:5
+   |
+LL |     U { unit: () };
+   |     ^^^^^^^^^^^^^^^
+
+error: unused return value of `U::method` that must be used
+  --> $DIR/unused_attributes-must_use.rs:106:5
+   |
+LL |     U::method();
+   |     ^^^^^^^^^^^^
+
+error: unused return value of `foo` that must be used
+  --> $DIR/unused_attributes-must_use.rs:107:5
+   |
+LL |     foo();
+   |     ^^^^^^
+
+error: unused return value of `foreign_foo` that must be used
+  --> $DIR/unused_attributes-must_use.rs:110:9
+   |
+LL |         foreign_foo();
+   |         ^^^^^^^^^^^^^^
+
+error: unused return value of `Use::get_four` that must be used
+  --> $DIR/unused_attributes-must_use.rs:118:5
+   |
+LL |     ().get_four();
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 26 previous errors
+
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
index d62625faaaa..902a6ec81d6 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
@@ -30,5 +30,4 @@ fn main() {
     //~^ ERROR this function takes 1 argument but 0 arguments were supplied
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 argument but 2 arguments were supplied
-    //~| ERROR mismatched types
 }
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index 9ae9c474162..264d7cbb9b1 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -18,12 +18,6 @@ note: associated function defined here
 LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
 
-error[E0308]: mismatched types
-  --> $DIR/overloaded-calls-bad.rs:31:17
-   |
-LL |     let ans = s("burma", "shave");
-   |                 ^^^^^^^ expected `isize`, found `&str`
-
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:31:15
    |
@@ -38,7 +32,7 @@ note: associated function defined here
 LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0057, E0308.
 For more information about an error, try `rustc --explain E0057`.
diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr
index 2b6314c38ce..b7516babc13 100644
--- a/src/test/ui/parser/expr-as-stmt-2.stderr
+++ b/src/test/ui/parser/expr-as-stmt-2.stderr
@@ -36,6 +36,11 @@ LL | /     &&
 LL | |     if let Some(y) = a { true } else { false }
    | |______________________________________________^ expected `bool`, found `&&bool`
    |
+help: consider removing the `&&`
+   |
+LL -     &&
+LL +     if let Some(y) = a { true } else { false }
+   | 
 help: parentheses are required to parse this as an expression
    |
 LL |     (if let Some(x) = a { true } else { false })
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index df0e4dcb16e..e63da52c8fe 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -170,6 +170,11 @@ LL | fn revenge_from_mars() -> bool {
 LL |     { true } && { true }
    |              ^^^^^^^^^^^ expected `bool`, found `&&bool`
    |
+help: consider removing the `&&`
+   |
+LL -     { true } && { true }
+LL +     { true } { true }
+   | 
 help: parentheses are required to parse this as an expression
    |
 LL |     ({ true }) && { true }
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 4c830554d43..897de54a7bf 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -676,6 +676,12 @@ error[E0308]: mismatched types
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |                                            ^^^^^^^ expected `bool`, found `&&bool`
+   |
+help: consider removing the `&&`
+   |
+LL -     if let Range { start: true, end } = t..&&false {}
+LL +     if let Range { start: true, end } = t..false {}
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:83:8
@@ -866,6 +872,12 @@ error[E0308]: mismatched types
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |                                               ^^^^^^^ expected `bool`, found `&&bool`
+   |
+help: consider removing the `&&`
+   |
+LL -     while let Range { start: true, end } = t..&&false {}
+LL +     while let Range { start: true, end } = t..false {}
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:147:11
diff --git a/src/test/ui/symbol-names/basic.legacy.stderr b/src/test/ui/symbol-names/basic.legacy.stderr
index 429e28e5241..e4d58d3ccdb 100644
--- a/src/test/ui/symbol-names/basic.legacy.stderr
+++ b/src/test/ui/symbol-names/basic.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN5basic4main17h611df9c6948c15f7E)
+error: symbol-name(_ZN5basic4main17h87acd86b3a6f1754E)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(basic::main::h611df9c6948c15f7)
+error: demangling(basic::main::h87acd86b3a6f1754)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/const-generics-demangling.legacy.stderr b/src/test/ui/symbol-names/const-generics-demangling.legacy.stderr
new file mode 100644
index 00000000000..bebbb7aac98
--- /dev/null
+++ b/src/test/ui/symbol-names/const-generics-demangling.legacy.stderr
@@ -0,0 +1,74 @@
+error: symbol-name(_ZN1c21Unsigned$LT$11_u8$GT$1f17h[HASH]E)
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(c::Unsigned<11_u8>::f::h[HASH])
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(c::Unsigned<11_u8>::f)
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1c22Signed$LT$.152_i16$GT$1f17h[HASH]E)
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(c::Signed<.152_i16>::f::h[HASH])
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(c::Signed<.152_i16>::f)
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1c13Bool$LT$_$GT$1f17h[HASH]E)
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(c::Bool<_>::f::h[HASH])
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(c::Bool<_>::f)
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1c13Char$LT$_$GT$1f17h[HASH]E)
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(c::Char<_>::f::h[HASH])
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(c::Char<_>::f)
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/symbol-names/const-generics-demangling.rs b/src/test/ui/symbol-names/const-generics-demangling.rs
index 5c40c391a9e..4a04eca67fd 100644
--- a/src/test/ui/symbol-names/const-generics-demangling.rs
+++ b/src/test/ui/symbol-names/const-generics-demangling.rs
@@ -1,38 +1,62 @@
 // build-fail
-// compile-flags: -C symbol-mangling-version=v0 --crate-name=c
-// normalize-stderr-test: "c\[.*?\]" -> "c[HASH]"
+// revisions: legacy v0
+// compile-flags: --crate-name=c
+//[legacy]compile-flags: -C symbol-mangling-version=legacy -Z unstable-options
+//    [v0]compile-flags: -C symbol-mangling-version=v0
+//[legacy]normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]"
+//    [v0]normalize-stderr-test: "c\[.*?\]" -> "c[HASH]"
 #![feature(rustc_attrs)]
 
 pub struct Unsigned<const F: u8>;
 
-#[rustc_symbol_name]
-//~^ ERROR symbol-name(_RMCs
-//~| ERROR demangling(<c[
-//~| ERROR demangling-alt(<c::Unsigned<11>>)
-impl Unsigned<11> {}
+impl Unsigned<11> {
+    #[rustc_symbol_name]
+    //[v0]~^ ERROR symbol-name(_RNvMCs
+    //[v0]~| ERROR demangling(<c[
+    //[v0]~| ERROR demangling-alt(<c::Unsigned<11>>::f)
+    //[legacy]~^^^^ ERROR symbol-name(_ZN1c21Unsigned$LT$11_u8$GT$
+    //[legacy]~|    ERROR demangling(c::Unsigned<11_u8>::f::
+    //[legacy]~|    ERROR demangling-alt(c::Unsigned<11_u8>::f)
+    fn f() {}
+}
 
 pub struct Signed<const F: i16>;
 
-#[rustc_symbol_name]
-//~^ ERROR symbol-name(_RMs_Cs
-//~| ERROR demangling(<c[
-//~| ERROR demangling-alt(<c::Signed<-152>>)
-impl Signed<-152> {}
+impl Signed<-152> {
+    #[rustc_symbol_name]
+    //[v0]~^ ERROR symbol-name(_RNvMs_Cs
+    //[v0]~| ERROR demangling(<c[
+    //[v0]~| ERROR demangling-alt(<c::Signed<-152>>::f)
+    //[legacy]~^^^^ ERROR symbol-name(_ZN1c22Signed$LT$.152_i16$GT$
+    //[legacy]~|    ERROR demangling(c::Signed<.152_i16>::f::
+    //[legacy]~|    ERROR demangling-alt(c::Signed<.152_i16>::f)
+    fn f() {}
+}
 
 pub struct Bool<const F: bool>;
 
-#[rustc_symbol_name]
-//~^ ERROR symbol-name(_RMs0_Cs
-//~| ERROR demangling(<c[
-//~| ERROR demangling-alt(<c::Bool<true>>)
-impl Bool<true> {}
+impl Bool<true> {
+    #[rustc_symbol_name]
+    //[v0]~^ ERROR symbol-name(_RNvMs0_Cs
+    //[v0]~| ERROR demangling(<c[
+    //[v0]~| ERROR demangling-alt(<c::Bool<true>>::f)
+    //[legacy]~^^^^ ERROR symbol-name(_ZN1c13Bool$LT$_$GT$
+    //[legacy]~|    ERROR demangling(c::Bool<_>::f::
+    //[legacy]~|    ERROR demangling-alt(c::Bool<_>::f)
+    fn f() {}
+}
 
 pub struct Char<const F: char>;
 
-#[rustc_symbol_name]
-//~^ ERROR symbol-name(_RMs1_Cs
-//~| ERROR demangling(<c[
-//~| ERROR demangling-alt(<c::Char<'∂'>>)
-impl Char<'∂'> {}
+impl Char<'∂'> {
+    #[rustc_symbol_name]
+    //[v0]~^ ERROR symbol-name(_RNvMs1_Cs
+    //[v0]~| ERROR demangling(<c[
+    //[v0]~| ERROR demangling-alt(<c::Char<'∂'>>::f)
+    //[legacy]~^^^^ ERROR symbol-name(_ZN1c13Char$LT$_$GT$
+    //[legacy]~|    ERROR demangling(c::Char<_>::f::
+    //[legacy]~|    ERROR demangling-alt(c::Char<_>::f)
+    fn f() {}
+}
 
 fn main() {}
diff --git a/src/test/ui/symbol-names/const-generics-demangling.stderr b/src/test/ui/symbol-names/const-generics-demangling.stderr
deleted file mode 100644
index 8aa08b8a22c..00000000000
--- a/src/test/ui/symbol-names/const-generics-demangling.stderr
+++ /dev/null
@@ -1,74 +0,0 @@
-error: symbol-name(_RMCsCRATE_HASH_1cINtB<REF>_8UnsignedKhb_E)
-  --> $DIR/const-generics-demangling.rs:8:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling(<c[HASH]::Unsigned<11u8>>)
-  --> $DIR/const-generics-demangling.rs:8:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling-alt(<c::Unsigned<11>>)
-  --> $DIR/const-generics-demangling.rs:8:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: symbol-name(_RMs_CsCRATE_HASH_1cINtB<REF>_6SignedKsn98_E)
-  --> $DIR/const-generics-demangling.rs:16:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling(<c[HASH]::Signed<-152i16>>)
-  --> $DIR/const-generics-demangling.rs:16:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling-alt(<c::Signed<-152>>)
-  --> $DIR/const-generics-demangling.rs:16:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB<REF>_4BoolKb1_E)
-  --> $DIR/const-generics-demangling.rs:24:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling(<c[HASH]::Bool<true>>)
-  --> $DIR/const-generics-demangling.rs:24:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling-alt(<c::Bool<true>>)
-  --> $DIR/const-generics-demangling.rs:24:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB<REF>_4CharKc2202_E)
-  --> $DIR/const-generics-demangling.rs:32:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling(<c[HASH]::Char<'∂'>>)
-  --> $DIR/const-generics-demangling.rs:32:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: demangling-alt(<c::Char<'∂'>>)
-  --> $DIR/const-generics-demangling.rs:32:1
-   |
-LL | #[rustc_symbol_name]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
-
diff --git a/src/test/ui/symbol-names/const-generics-demangling.v0.stderr b/src/test/ui/symbol-names/const-generics-demangling.v0.stderr
new file mode 100644
index 00000000000..7238a849332
--- /dev/null
+++ b/src/test/ui/symbol-names/const-generics-demangling.v0.stderr
@@ -0,0 +1,74 @@
+error: symbol-name(_RNvMCsCRATE_HASH_1cINtB<REF>_8UnsignedKhb_E1f)
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(<c[HASH]::Unsigned<11u8>>::f)
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(<c::Unsigned<11>>::f)
+  --> $DIR/const-generics-demangling.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_RNvMs_CsCRATE_HASH_1cINtB<REF>_6SignedKsn98_E1f)
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(<c[HASH]::Signed<-152i16>>::f)
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(<c::Signed<-152>>::f)
+  --> $DIR/const-generics-demangling.rs:26:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_RNvMs0_CsCRATE_HASH_1cINtB<REF>_4BoolKb1_E1f)
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(<c[HASH]::Bool<true>>::f)
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(<c::Bool<true>>::f)
+  --> $DIR/const-generics-demangling.rs:39:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_RNvMs1_CsCRATE_HASH_1cINtB<REF>_4CharKc2202_E1f)
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(<c[HASH]::Char<'∂'>>::f)
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(<c::Char<'∂'>>::f)
+  --> $DIR/const-generics-demangling.rs:52:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/symbol-names/issue-60925.legacy.stderr b/src/test/ui/symbol-names/issue-60925.legacy.stderr
index 0e36747fb80..c987ebc5343 100644
--- a/src/test/ui/symbol-names/issue-60925.legacy.stderr
+++ b/src/test/ui/symbol-names/issue-60925.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h5425dadb5b1e5fb6E)
+error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h8d22952c45e20d65E)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h5425dadb5b1e5fb6)
+error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h8d22952c45e20d65)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/types.legacy.stderr b/src/test/ui/symbol-names/types.legacy.stderr
new file mode 100644
index 00000000000..a4984d5629f
--- /dev/null
+++ b/src/test/ui/symbol-names/types.legacy.stderr
@@ -0,0 +1,470 @@
+error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E)
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<bool>::h[HASH])
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<bool>)
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E)
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<char>::h[HASH])
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<char>)
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E)
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i8>::h[HASH])
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i8>)
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E)
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i16>::h[HASH])
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i16>)
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E)
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i32>::h[HASH])
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i32>)
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E)
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i64>::h[HASH])
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i64>)
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u8>::h[HASH])
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u8>)
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E)
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u16>::h[HASH])
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u16>)
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E)
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u32>::h[HASH])
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u32>)
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E)
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u64>::h[HASH])
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u64>)
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E)
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<f32>::h[HASH])
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<f32>)
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E)
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<f64>::h[HASH])
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<f64>)
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<str>::h[HASH])
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<str>)
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E)
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<!>::h[HASH])
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<!>)
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<()>::h[HASH])
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<()>)
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,)>::h[HASH])
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,)>)
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,u16)>::h[HASH])
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,u16)>)
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH])
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,u16,u32)>)
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<*const u8>::h[HASH])
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<*const u8>)
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<*mut u8>::h[HASH])
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<*mut u8>)
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<&str>::h[HASH])
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<&str>)
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<&mut str>::h[HASH])
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<&mut str>)
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[u8; 0]>::h[HASH])
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[u8; 0]>)
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<fn()>::h[HASH])
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<fn()>)
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<unsafe extern "C" fn()>::h[HASH])
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<unsafe extern "C" fn()>)
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[T; N]>::h[HASH])
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[T; N]>)
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 78 previous errors
+
diff --git a/src/test/ui/symbol-names/types.rs b/src/test/ui/symbol-names/types.rs
new file mode 100644
index 00000000000..0ae699c93c2
--- /dev/null
+++ b/src/test/ui/symbol-names/types.rs
@@ -0,0 +1,170 @@
+// build-fail
+// revisions: legacy verbose-legacy
+// compile-flags: --crate-name=a -C symbol-mangling-version=legacy -Z unstable-options
+//[verbose-legacy]compile-flags: -Zverbose
+// normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]"
+
+#![feature(never_type)]
+#![feature(rustc_attrs)]
+
+pub fn b() {
+    struct Type<T: ?Sized>(T);
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b16Type$LT$bool$GT$
+    //~| ERROR demangling(a::b::Type<bool>::
+    //~| ERROR demangling-alt(a::b::Type<bool>)
+    impl Type<bool> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b16Type$LT$char$GT$
+    //~| ERROR demangling(a::b::Type<char>::
+    //~| ERROR demangling-alt(a::b::Type<char>)
+    impl Type<char> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b14Type$LT$i8$GT$
+    //~| ERROR demangling(a::b::Type<i8>::
+    //~| ERROR demangling-alt(a::b::Type<i8>)
+    impl Type<i8> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i16$GT$
+    //~| ERROR demangling(a::b::Type<i16>::
+    //~| ERROR demangling-alt(a::b::Type<i16>)
+    impl Type<i16> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i32$GT$
+    //~| ERROR demangling(a::b::Type<i32>::
+    //~| ERROR demangling-alt(a::b::Type<i32>)
+    impl Type<i32> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i64$GT$
+    //~| ERROR demangling(a::b::Type<i64>::
+    //~| ERROR demangling-alt(a::b::Type<i64>)
+    impl Type<i64> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b14Type$LT$u8$GT$
+    //~| ERROR demangling(a::b::Type<u8>::
+    //~| ERROR demangling-alt(a::b::Type<u8>)
+    impl Type<u8> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u16$GT$
+    //~| ERROR demangling(a::b::Type<u16>::
+    //~| ERROR demangling-alt(a::b::Type<u16>)
+    impl Type<u16> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u32$GT$
+    //~| ERROR demangling(a::b::Type<u32>::
+    //~| ERROR demangling-alt(a::b::Type<u32>)
+    impl Type<u32> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u64$GT$
+    //~| ERROR demangling(a::b::Type<u64>::
+    //~| ERROR demangling-alt(a::b::Type<u64>)
+    impl Type<u64> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f32$GT$
+    //~| ERROR demangling(a::b::Type<f32>::
+    //~| ERROR demangling-alt(a::b::Type<f32>)
+    impl Type<f32> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f64$GT$
+    //~| ERROR demangling(a::b::Type<f64>::
+    //~| ERROR demangling-alt(a::b::Type<f64>)
+    impl Type<f64> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b15Type$LT$str$GT$
+    //~| ERROR demangling(a::b::Type<str>::
+    //~| ERROR demangling-alt(a::b::Type<str>)
+    impl Type<str> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b17Type$LT$$u21$$GT$
+    //~| ERROR demangling(a::b::Type<!>::
+    //~| ERROR demangling-alt(a::b::Type<!>)
+    impl Type<!> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT
+    //~| ERROR demangling(a::b::Type<()>::
+    //~| ERROR demangling-alt(a::b::Type<()>)
+    impl Type<()> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$
+    //~| ERROR demangling(a::b::Type<(u8,)>::
+    //~| ERROR demangling-alt(a::b::Type<(u8,)>)
+    impl Type<(u8,)> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$
+    //~| ERROR demangling(a::b::Type<(u8,u16)>::
+    //~| ERROR demangling-alt(a::b::Type<(u8,u16)>)
+    impl Type<(u8,u16)> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$
+    //~| ERROR demangling(a::b::Type<(u8,u16,u32)>::
+    //~| ERROR demangling-alt(a::b::Type<(u8,u16,u32)>)
+    impl Type<(u8,u16,u32)> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$
+    //~| ERROR demangling(a::b::Type<*const u8>::
+    //~| ERROR demangling-alt(a::b::Type<*const u8>)
+    impl Type<*const u8> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$
+    //~| ERROR demangling(a::b::Type<*mut u8>::
+    //~| ERROR demangling-alt(a::b::Type<*mut u8>)
+    impl Type<*mut u8> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$
+    //~| ERROR demangling(a::b::Type<&str>::
+    //~| ERROR demangling-alt(a::b::Type<&str>)
+    impl Type<&str> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$
+    //~| ERROR demangling(a::b::Type<&mut str>::
+    //~| ERROR demangling-alt(a::b::Type<&mut str>)
+    impl Type<&mut str> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$
+    //~| ERROR demangling(a::b::Type<[u8; 0]>::
+    //~| ERROR demangling-alt(a::b::Type<[u8; 0]>)
+    impl Type<[u8; 0]> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$
+    //~| ERROR demangling(a::b::Type<fn()>::
+    //~| ERROR demangling-alt(a::b::Type<fn()>)
+    impl Type<fn()> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$
+    //~| ERROR demangling(a::b::Type<unsafe extern "C" fn()>::
+    //~| ERROR demangling-alt(a::b::Type<unsafe extern "C" fn()>)
+    impl Type<unsafe extern "C" fn()> {}
+
+    #[rustc_symbol_name]
+    //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$
+    //~| ERROR demangling(a::b::Type<[T; N]>::
+    //~| ERROR demangling-alt(a::b::Type<[T; N]>)
+    impl<const N: usize, T> Type<[T; N]> {}
+}
+
+fn main() {}
diff --git a/src/test/ui/symbol-names/types.verbose-legacy.stderr b/src/test/ui/symbol-names/types.verbose-legacy.stderr
new file mode 100644
index 00000000000..a4984d5629f
--- /dev/null
+++ b/src/test/ui/symbol-names/types.verbose-legacy.stderr
@@ -0,0 +1,470 @@
+error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E)
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<bool>::h[HASH])
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<bool>)
+  --> $DIR/types.rs:13:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E)
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<char>::h[HASH])
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<char>)
+  --> $DIR/types.rs:19:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E)
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i8>::h[HASH])
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i8>)
+  --> $DIR/types.rs:25:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E)
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i16>::h[HASH])
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i16>)
+  --> $DIR/types.rs:31:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E)
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i32>::h[HASH])
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i32>)
+  --> $DIR/types.rs:37:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E)
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<i64>::h[HASH])
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<i64>)
+  --> $DIR/types.rs:43:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u8>::h[HASH])
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u8>)
+  --> $DIR/types.rs:49:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E)
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u16>::h[HASH])
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u16>)
+  --> $DIR/types.rs:55:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E)
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u32>::h[HASH])
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u32>)
+  --> $DIR/types.rs:61:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E)
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<u64>::h[HASH])
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<u64>)
+  --> $DIR/types.rs:67:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E)
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<f32>::h[HASH])
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<f32>)
+  --> $DIR/types.rs:73:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E)
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<f64>::h[HASH])
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<f64>)
+  --> $DIR/types.rs:79:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<str>::h[HASH])
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<str>)
+  --> $DIR/types.rs:85:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E)
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<!>::h[HASH])
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<!>)
+  --> $DIR/types.rs:91:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<()>::h[HASH])
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<()>)
+  --> $DIR/types.rs:97:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,)>::h[HASH])
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,)>)
+  --> $DIR/types.rs:103:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,u16)>::h[HASH])
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,u16)>)
+  --> $DIR/types.rs:109:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH])
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<(u8,u16,u32)>)
+  --> $DIR/types.rs:115:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<*const u8>::h[HASH])
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<*const u8>)
+  --> $DIR/types.rs:121:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E)
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<*mut u8>::h[HASH])
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<*mut u8>)
+  --> $DIR/types.rs:127:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<&str>::h[HASH])
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<&str>)
+  --> $DIR/types.rs:133:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E)
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<&mut str>::h[HASH])
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<&mut str>)
+  --> $DIR/types.rs:139:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[u8; 0]>::h[HASH])
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[u8; 0]>)
+  --> $DIR/types.rs:145:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<fn()>::h[HASH])
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<fn()>)
+  --> $DIR/types.rs:151:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E)
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<unsafe extern "C" fn()>::h[HASH])
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<unsafe extern "C" fn()>)
+  --> $DIR/types.rs:157:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E)
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling(a::b::Type<[T; N]>::h[HASH])
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: demangling-alt(a::b::Type<[T; N]>)
+  --> $DIR/types.rs:163:5
+   |
+LL |     #[rustc_symbol_name]
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 78 previous errors
+
diff --git a/src/test/ui/tuple/wrong_argument_ice-2.rs b/src/test/ui/tuple/wrong_argument_ice-2.rs
new file mode 100644
index 00000000000..b0f814616f2
--- /dev/null
+++ b/src/test/ui/tuple/wrong_argument_ice-2.rs
@@ -0,0 +1,17 @@
+fn test(t: (i32, i32)) {}
+
+struct Foo;
+
+impl Foo {
+    fn qux(&self) -> i32 {
+        0
+    }
+}
+
+fn bar() {
+    let x = Foo;
+    test(x.qux(), x.qux());
+    //~^ ERROR this function takes 1 argument but 2 arguments were supplied
+}
+
+fn main() {}
diff --git a/src/test/ui/tuple/wrong_argument_ice-2.stderr b/src/test/ui/tuple/wrong_argument_ice-2.stderr
new file mode 100644
index 00000000000..ddafc9763e7
--- /dev/null
+++ b/src/test/ui/tuple/wrong_argument_ice-2.stderr
@@ -0,0 +1,19 @@
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
+  --> $DIR/wrong_argument_ice-2.rs:13:5
+   |
+LL |     test(x.qux(), x.qux());
+   |     ^^^^ -------  ------- supplied 2 arguments
+   |
+note: function defined here
+  --> $DIR/wrong_argument_ice-2.rs:1:4
+   |
+LL | fn test(t: (i32, i32)) {}
+   |    ^^^^ -------------
+help: use parentheses to construct a tuple
+   |
+LL |     test((x.qux(), x.qux()));
+   |          +                +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/typeck/deref-multi.rs b/src/test/ui/typeck/deref-multi.rs
new file mode 100644
index 00000000000..3dc4771fefb
--- /dev/null
+++ b/src/test/ui/typeck/deref-multi.rs
@@ -0,0 +1,26 @@
+fn a(x: &&i32) -> i32 {
+    x
+    //~^ ERROR mismatched types
+}
+
+fn a2(x: &&&&&i32) -> i32 {
+    x
+    //~^ ERROR mismatched types
+}
+
+fn b(x: &i32) -> i32 {
+    &x
+    //~^ ERROR mismatched types
+}
+
+fn c(x: Box<i32>) -> i32 {
+    &x
+    //~^ ERROR mismatched types
+}
+
+fn d(x: std::sync::Mutex<&i32>) -> i32 {
+    x.lock().unwrap()
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/deref-multi.stderr b/src/test/ui/typeck/deref-multi.stderr
new file mode 100644
index 00000000000..bd6575c73d2
--- /dev/null
+++ b/src/test/ui/typeck/deref-multi.stderr
@@ -0,0 +1,72 @@
+error[E0308]: mismatched types
+  --> $DIR/deref-multi.rs:2:5
+   |
+LL | fn a(x: &&i32) -> i32 {
+   |                   --- expected `i32` because of return type
+LL |     x
+   |     ^ expected `i32`, found `&&i32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     **x
+   |     ++
+
+error[E0308]: mismatched types
+  --> $DIR/deref-multi.rs:7:5
+   |
+LL | fn a2(x: &&&&&i32) -> i32 {
+   |                       --- expected `i32` because of return type
+LL |     x
+   |     ^ expected `i32`, found `&&&&&i32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     *****x
+   |     +++++
+
+error[E0308]: mismatched types
+  --> $DIR/deref-multi.rs:12:5
+   |
+LL | fn b(x: &i32) -> i32 {
+   |                  --- expected `i32` because of return type
+LL |     &x
+   |     ^^ expected `i32`, found `&&i32`
+   |
+help: consider removing the `&` and dereferencing the borrow instead
+   |
+LL |     *x
+   |     ~
+
+error[E0308]: mismatched types
+  --> $DIR/deref-multi.rs:17:5
+   |
+LL | fn c(x: Box<i32>) -> i32 {
+   |                      --- expected `i32` because of return type
+LL |     &x
+   |     ^^ expected `i32`, found `&Box<i32>`
+   |
+   = note:   expected type `i32`
+           found reference `&Box<i32>`
+help: consider removing the `&` and dereferencing the borrow instead
+   |
+LL |     *x
+   |     ~
+
+error[E0308]: mismatched types
+  --> $DIR/deref-multi.rs:22:5
+   |
+LL | fn d(x: std::sync::Mutex<&i32>) -> i32 {
+   |                                    --- expected `i32` because of return type
+LL |     x.lock().unwrap()
+   |     ^^^^^^^^^^^^^^^^^ expected `i32`, found struct `MutexGuard`
+   |
+   = note: expected type `i32`
+            found struct `MutexGuard<'_, &i32>`
+help: consider dereferencing the type
+   |
+LL |     **x.lock().unwrap()
+   |     ++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d6cdde584a1f15ea086bae922e20fd27f716543
+Subproject 3d6970d50e30e797b8e26b2b9b1bdf92dc381f3