diff --git a/Cargo.lock b/Cargo.lock
index fb7d2a4ac2fc6..fd27f05363832 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -183,7 +183,16 @@ dependencies = [
  "block-padding",
  "byte-tools",
  "byteorder",
- "generic-array",
+ "generic-array 0.12.3",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array 0.14.4",
 ]
 
 [[package]]
@@ -233,8 +242,11 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "flate2",
+ "hex 0.4.2",
+ "rayon",
  "serde",
  "serde_json",
+ "sha2",
  "tar",
  "toml",
 ]
@@ -687,6 +699,12 @@ version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
 
+[[package]]
+name = "cpuid-bool"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
+
 [[package]]
 name = "crates-io"
 version = "0.31.1"
@@ -884,7 +902,16 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 dependencies = [
- "generic-array",
+ "generic-array 0.12.3",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array 0.14.4",
 ]
 
 [[package]]
@@ -1166,6 +1193,16 @@ dependencies = [
  "typenum",
 ]
 
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
 [[package]]
 name = "getopts"
 version = "0.2.21"
@@ -1835,9 +1872,9 @@ version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
 dependencies = [
- "block-buffer",
- "digest",
- "opaque-debug",
+ "block-buffer 0.7.3",
+ "digest 0.8.1",
+ "opaque-debug 0.2.3",
 ]
 
 [[package]]
@@ -2097,6 +2134,12 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
 
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
 [[package]]
 name = "open"
 version = "1.4.0"
@@ -4362,10 +4405,23 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
 dependencies = [
- "block-buffer",
- "digest",
+ "block-buffer 0.7.3",
+ "digest 0.8.1",
  "fake-simd",
- "opaque-debug",
+ "opaque-debug 0.2.3",
+]
+
+[[package]]
+name = "sha2"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpuid-bool",
+ "digest 0.9.0",
+ "opaque-debug 0.3.0",
 ]
 
 [[package]]
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 5cd0a56d52414..cd018ae1204f9 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -581,7 +581,7 @@ declare_features! (
     /// Allows `if let` guard in match arms.
     (active, if_let_guard, "1.47.0", Some(51114), None),
 
-    /// Allows non trivial generic constants which have to be manually propageted upwards.
+    /// Allows non-trivial generic constants which have to be manually propageted upwards.
     (active, const_evaluatable_checked, "1.48.0", Some(76560), None),
 
     /// Allows basic arithmetic on floating point types in a `const fn`.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 96fde48d96cc1..62b1254287724 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -341,9 +341,7 @@ impl<T> PerNS<Option<T>> {
 
     /// Returns an iterator over the items which are `Some`.
     pub fn present_items(self) -> impl Iterator<Item = T> {
-        use std::iter::once;
-
-        once(self.type_ns).chain(once(self.value_ns)).chain(once(self.macro_ns)).filter_map(|it| it)
+        IntoIter::new([self.type_ns, self.value_ns, self.macro_ns]).filter_map(|it| it)
     }
 }
 
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 1efc8bc3124b6..fd6a312ef3af9 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -9,13 +9,13 @@ use crate::{Item, ItemKind, TraitItem, TraitItemKind};
 
 use std::fmt::{self, Display};
 
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum MethodKind {
     Trait { body: bool },
     Inherent,
 }
 
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum Target {
     ExternCrate,
     Use,
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 32e233e337da3..9a1b77e994d13 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -41,18 +41,6 @@ pub trait NonConstOp: std::fmt::Debug {
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx>;
 }
 
-#[derive(Debug)]
-pub struct Abort;
-impl NonConstOp for Abort {
-    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
-        mcf_status_in_item(ccx)
-    }
-
-    fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-        mcf_build_error(ccx, span, "abort is not stable in const fn")
-    }
-}
-
 #[derive(Debug)]
 pub struct FloatingPointOp;
 impl NonConstOp for FloatingPointOp {
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 4e714bfeed310..94806116eaf2e 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -434,11 +434,13 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
     fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &BasicBlockData<'tcx>) {
         trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup);
 
-        // Just as the old checker did, we skip const-checking basic blocks on the unwind path.
-        // These blocks often drop locals that would otherwise be returned from the function.
+        // We don't const-check basic blocks on the cleanup path since we never unwind during
+        // const-eval: a panic causes an immediate compile error. In other words, cleanup blocks
+        // are unreachable during const-eval.
         //
-        // FIXME: This shouldn't be unsound since a panic at compile time will cause a compiler
-        // error anyway, but maybe we should do more here?
+        // We can't be more conservative (e.g., by const-checking cleanup blocks anyways) because
+        // locals that would never be dropped during normal execution are sometimes dropped during
+        // unwinding, which means backwards-incompatible live-drop errors.
         if block.is_cleanup {
             return;
         }
@@ -874,12 +876,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
             }
 
             TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
-            TerminatorKind::Abort => self.check_op(ops::Abort),
 
             TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
                 self.check_op(ops::Generator(hir::GeneratorKind::Gen))
             }
 
+            TerminatorKind::Abort => {
+                // Cleanup blocks are skipped for const checking (see `visit_basic_block_data`).
+                span_bug!(self.span, "`Abort` terminator outside of cleanup block")
+            }
+
             TerminatorKind::Assert { .. }
             | TerminatorKind::FalseEdge { .. }
             | TerminatorKind::FalseUnwind { .. }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index b52216c45ce95..59955b2733420 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -13,12 +13,14 @@ use rustc_errors::{pluralize, struct_span_err};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
-use rustc_hir::{self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem};
+use rustc_hir::{
+    self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID,
+};
 use rustc_hir::{MethodKind, Target};
 use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES};
 use rustc_session::parse::feature_err;
-use rustc_span::symbol::sym;
-use rustc_span::Span;
+use rustc_span::symbol::{sym, Symbol};
+use rustc_span::{Span, DUMMY_SP};
 
 pub(crate) fn target_from_impl_item<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -333,6 +335,17 @@ impl CheckAttrVisitor<'tcx> {
                                 .emit();
                             return false;
                         }
+                        if CRATE_HIR_ID == hir_id {
+                            self.tcx
+                                .sess
+                                .struct_span_err(
+                                    meta.span(),
+                                    "`#![doc(alias = \"...\")]` isn't allowed as a crate \
+                                     level attribute",
+                                )
+                                .emit();
+                            return false;
+                        }
                     }
                 }
             }
@@ -808,9 +821,46 @@ fn is_c_like_enum(item: &Item<'_>) -> bool {
     }
 }
 
+fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
+    const ATTRS_TO_CHECK: &[Symbol] = &[
+        sym::macro_export,
+        sym::repr,
+        sym::path,
+        sym::automatically_derived,
+        sym::start,
+        sym::main,
+    ];
+
+    for attr in attrs {
+        for attr_to_check in ATTRS_TO_CHECK {
+            if tcx.sess.check_name(attr, *attr_to_check) {
+                tcx.sess
+                    .struct_span_err(
+                        attr.span,
+                        &format!(
+                            "`{}` attribute cannot be used at crate level",
+                            attr_to_check.to_ident_string()
+                        ),
+                    )
+                    .emit();
+            }
+        }
+    }
+}
+
 fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     tcx.hir()
         .visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor());
+    if module_def_id.is_top_level_module() {
+        CheckAttrVisitor { tcx }.check_attributes(
+            CRATE_HIR_ID,
+            tcx.hir().krate_attrs(),
+            &DUMMY_SP,
+            Target::Mod,
+            None,
+        );
+        check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
+    }
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 8aa6e7936bef6..e87adb378e7f7 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -78,29 +78,38 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
 // Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
 // (with `ast::Item`), so make sure to keep them in sync.
 fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPointType {
-    match item.kind {
-        ItemKind::Fn(..) => {
-            if sess.contains_name(&item.attrs, sym::start) {
-                EntryPointType::Start
-            } else if sess.contains_name(&item.attrs, sym::main) {
-                EntryPointType::MainAttr
-            } else if item.ident.name == sym::main {
-                if at_root {
-                    // This is a top-level function so can be `main`.
-                    EntryPointType::MainNamed
-                } else {
-                    EntryPointType::OtherMain
-                }
-            } else {
-                EntryPointType::None
-            }
+    if sess.contains_name(&item.attrs, sym::start) {
+        EntryPointType::Start
+    } else if sess.contains_name(&item.attrs, sym::main) {
+        EntryPointType::MainAttr
+    } else if item.ident.name == sym::main {
+        if at_root {
+            // This is a top-level function so can be `main`.
+            EntryPointType::MainNamed
+        } else {
+            EntryPointType::OtherMain
         }
-        _ => EntryPointType::None,
+    } else {
+        EntryPointType::None
     }
 }
 
+fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
+    sess.struct_span_err(span, &format!("`{}` attribute can only be used on functions", attr))
+        .emit();
+}
+
 fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
     match entry_point_type(&ctxt.session, item, at_root) {
+        EntryPointType::None => (),
+        _ if !matches!(item.kind, ItemKind::Fn(..)) => {
+            if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::start) {
+                throw_attr_err(&ctxt.session, attr.span, "start");
+            }
+            if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::main) {
+                throw_attr_err(&ctxt.session, attr.span, "main");
+            }
+        }
         EntryPointType::MainNamed => {
             if ctxt.main_fn.is_none() {
                 ctxt.main_fn = Some((item.hir_id, item.span));
@@ -137,7 +146,6 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
                     .emit();
             }
         }
-        EntryPointType::None => (),
     }
 }
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 612bc3e74911c..e3cf6d12bd5eb 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -469,7 +469,7 @@ impl<'a> Resolver<'a> {
             ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
                 let mut err = self.session.struct_span_err(
                     span,
-                    "generic parameters must not be used inside of non trivial constant values",
+                    "generic parameters must not be used inside of non-trivial constant values",
                 );
                 err.span_label(
                     span,
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 283db1404d0a4..fe8f592638594 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -218,7 +218,7 @@ enum ResolutionError<'a> {
     ParamInTyOfConstParam(Symbol),
     /// constant values inside of type parameter defaults must not depend on generic parameters.
     ParamInAnonConstInTyDefault(Symbol),
-    /// generic parameters must not be used inside of non trivial constant values.
+    /// generic parameters must not be used inside of non-trivial constant values.
     ///
     /// This error is only emitted when using `min_const_generics`.
     ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs
index 0cc97fb4541d1..3e899e00d11f1 100644
--- a/compiler/rustc_session/src/lint/builtin.rs
+++ b/compiler/rustc_session/src/lint/builtin.rs
@@ -518,7 +518,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
-    /// #![macro_export]
+    /// #![ignore]
     /// ```
     ///
     /// {{produces}}
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index ddeab340f381b..406e8936e6ecf 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -11,6 +11,7 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(array_value_iter)]
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(drain_filter)]
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 90a8d9634ae1e..967374ffdc2c0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1907,6 +1907,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
                 let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
                 let ty = parent_trait_ref.skip_binder().self_ty();
+                if parent_trait_ref.references_error() {
+                    err.cancel();
+                    return;
+                }
+
                 err.note(&format!("required because it appears within the type `{}`", ty));
                 obligated_types.push(ty);
 
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 2f2ac9f094dc2..8fc14cb29971d 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -24,6 +24,7 @@ use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 use smallvec::SmallVec;
 
+use std::array;
 use std::iter;
 
 pub use crate::traits::{MethodViolationCode, ObjectSafetyViolation};
@@ -652,8 +653,7 @@ fn receiver_is_dispatchable<'tcx>(
         let caller_bounds: Vec<Predicate<'tcx>> = param_env
             .caller_bounds()
             .iter()
-            .chain(iter::once(unsize_predicate))
-            .chain(iter::once(trait_predicate))
+            .chain(array::IntoIter::new([unsize_predicate, trait_predicate]))
             .collect();
 
         ty::ParamEnv::new(tcx.intern_predicates(&caller_bounds), param_env.reveal())
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index b54de1d091608..b867798c76cf7 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -562,7 +562,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 .args
                 .iter()
                 .filter_map(|arg| match arg {
-                    GenericArg::Type(_) => Some(arg.span()),
+                    GenericArg::Type(_) | GenericArg::Const(_) => Some(arg.span()),
                     _ => None,
                 })
                 .collect::<Vec<_>>();
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 46b8b2e14c736..170ca2ce744cd 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -35,8 +35,8 @@ use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 use rustc_trait_selection::traits::wf::object_region_bounds;
 
 use smallvec::SmallVec;
+use std::array;
 use std::collections::BTreeSet;
-use std::iter;
 use std::slice;
 
 #[derive(Debug)]
@@ -1346,7 +1346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
 
             let is_equality = is_equality();
-            let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
+            let bounds = array::IntoIter::new([bound, bound2]).chain(matching_candidates);
             let mut err = if is_equality.is_some() {
                 // More specific Error Index entry.
                 struct_span_err!(
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 9aca112a9142d..1f4f40fca9be3 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -222,6 +222,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
                 hir::GenericParamKind::Const { .. } => {
                     let def_id = self.tcx.hir().local_def_id(param.hir_id);
                     self.tcx.ensure().type_of(def_id);
+                    // FIXME(const_generics:defaults)
                 }
             }
         }
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 21fb92ec8891a..7efda54fbe035 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -56,6 +56,7 @@ This API is completely unstable and subject to change.
 */
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(array_value_iter)]
 #![feature(bool_to_option)]
 #![feature(box_syntax)]
 #![feature(crate_visibility_modifier)]
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index ba08f65f903e5..880627e94c334 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -9,11 +9,8 @@
 // struct Node<K, V, height: usize> {
 //     keys: [K; 2 * B - 1],
 //     vals: [V; 2 * B - 1],
-//     edges: if height > 0 {
-//         [Box<Node<K, V, height - 1>>; 2 * B]
-//     } else { () },
-//     parent: Option<NonNull<Node<K, V, height + 1>>>,
-//     parent_idx: u16,
+//     edges: [if height > 0 { Box<Node<K, V, height - 1>> } else { () }; 2 * B],
+//     parent: Option<(NonNull<Node<K, V, height + 1>>, u16)>,
 //     len: u16,
 // }
 // ```
@@ -28,8 +25,8 @@
 //
 // - Trees must have uniform depth/height. This means that every path down to a leaf from a
 //   given node has exactly the same length.
-// - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges.
-//   This implies that even an empty internal node has at least one edge.
+// - A node of length `n` has `n` keys, `n` values, and `n + 1` edges.
+//   This implies that even an empty node has at least one edge.
 
 use core::cmp::Ordering;
 use core::marker::PhantomData;
@@ -298,9 +295,8 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
 }
 
 impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
-    /// Finds the length of the node. This is the number of keys or values. In an
-    /// internal node, the number of edges is `len() + 1`.
-    /// For any node, the number of possible edge handles is also `len() + 1`.
+    /// Finds the length of the node. This is the number of keys or values.
+    /// The number of edges is `len() + 1`.
     /// Note that, despite being safe, calling this function can have the side effect
     /// of invalidating mutable references that unsafe code has created.
     pub fn len(&self) -> usize {
@@ -321,9 +317,6 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     }
 
     /// Exposes the leaf portion of any leaf or internal node.
-    /// If the node is a leaf, this function simply opens up its data.
-    /// If the node is an internal node, so not a leaf, it does have all the data a leaf has
-    /// (header, keys and values), and this function exposes that.
     ///
     /// Returns a raw ptr to avoid invalidating other references to this node,
     /// which is possible when BorrowType is marker::ValMut.
@@ -471,9 +464,6 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     }
 
     /// Exposes the leaf portion of any leaf or internal node for writing.
-    /// If the node is a leaf, this function simply opens up its data.
-    /// If the node is an internal node, so not a leaf, it does have all the data a leaf has
-    /// (header, keys and values), and this function exposes that.
     ///
     /// We don't need to return a raw ptr because we have unique access to the entire node.
     fn as_leaf_mut(&mut self) -> &'a mut LeafNode<K, V> {
@@ -484,7 +474,7 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     ///
     /// # Safety
     /// The node has more than `idx` initialized elements.
-    pub unsafe fn key_mut_at(&mut self, idx: usize) -> &mut K {
+    unsafe fn key_mut_at(&mut self, idx: usize) -> &mut K {
         unsafe { self.reborrow_mut().into_key_mut_at(idx) }
     }
 
@@ -492,7 +482,7 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
     ///
     /// # Safety
     /// The node has more than `idx` initialized elements.
-    pub unsafe fn val_mut_at(&mut self, idx: usize) -> &mut V {
+    unsafe fn val_mut_at(&mut self, idx: usize) -> &mut V {
         unsafe { self.reborrow_mut().into_val_mut_at(idx) }
     }
 
@@ -655,7 +645,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
 
     /// Adds a key/value pair, and an edge to go to the left of that pair,
     /// to the beginning of the node.
-    pub fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
+    fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
         assert!(edge.height == self.height - 1);
         assert!(self.len() < CAPACITY);
 
@@ -679,9 +669,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
 }
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
-    /// Removes a key/value pair from the end of this node and returns the pair.
-    /// If this is an internal node, also removes the edge that was to the right
-    /// of that pair and returns the orphaned node that this edge owned.
+    /// Removes a key/value pair from the end of the node and returns the pair.
+    /// Also removes the edge that was to the right of that pair and, if the node
+    /// is internal, returns the orphaned subtree that this edge owned.
     fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
         debug_assert!(self.len() > 0);
 
@@ -705,9 +695,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
         }
     }
 
-    /// Removes a key/value pair from the beginning of this node and returns the pair.
-    /// If this is an internal node, also removes the edge that was to the left
-    /// of that pair and returns the orphaned node that this edge owned.
+    /// Removes a key/value pair from the beginning of the node and returns the pair.
+    /// Also removes the edge that was to the left of that pair and, if the node is
+    /// internal, returns the orphaned subtree that this edge owned.
     fn pop_front(&mut self) -> (K, V, Option<Root<K, V>>) {
         debug_assert!(self.len() > 0);
 
@@ -1011,18 +1001,18 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
             let (middle_kv_idx, insertion) = splitpoint(self.idx);
             let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
             let (mut left, k, v, mut right) = middle.split();
-            match insertion {
+            let mut insertion_edge = match insertion {
                 InsertionPlace::Left(insert_idx) => unsafe {
-                    Handle::new_edge(left.reborrow_mut(), insert_idx).insert_fit(key, val, edge);
+                    Handle::new_edge(left.reborrow_mut(), insert_idx)
                 },
                 InsertionPlace::Right(insert_idx) => unsafe {
                     Handle::new_edge(
                         right.node_as_mut().cast_unchecked::<marker::Internal>(),
                         insert_idx,
                     )
-                    .insert_fit(key, val, edge);
                 },
-            }
+            };
+            insertion_edge.insert_fit(key, val, edge);
             InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right })
         }
     }
diff --git a/library/alloc/src/collections/vec_deque.rs b/library/alloc/src/collections/vec_deque.rs
index 8e9acc42d9aba..adb08543334f0 100644
--- a/library/alloc/src/collections/vec_deque.rs
+++ b/library/alloc/src/collections/vec_deque.rs
@@ -9,10 +9,11 @@
 
 // ignore-tidy-filelength
 
+use core::array;
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{Hash, Hasher};
-use core::iter::{once, repeat_with, FromIterator, FusedIterator};
+use core::iter::{repeat_with, FromIterator, FusedIterator};
 use core::mem::{self, replace, ManuallyDrop};
 use core::ops::{Index, IndexMut, Range, RangeBounds, Try};
 use core::ptr::{self, NonNull};
@@ -99,7 +100,7 @@ impl<'a, 'b, T> PairSlices<'a, 'b, T> {
     }
 
     fn remainder(self) -> impl Iterator<Item = &'b [T]> {
-        once(self.b0).chain(once(self.b1))
+        array::IntoIter::new([self.b0, self.b1])
     }
 }
 
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b33cb3ad8e839..046c3867d8403 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -77,6 +77,7 @@
 #![cfg_attr(test, feature(new_uninit))]
 #![feature(allocator_api)]
 #![feature(array_chunks)]
+#![feature(array_value_iter)]
 #![feature(array_windows)]
 #![feature(allow_internal_unstable)]
 #![feature(arbitrary_self_types)]
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index c1038ce4260bc..54772ebb523a3 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -102,7 +102,7 @@ pub struct Error;
 /// library. The [`write!`] macro accepts an instance of [`io::Write`], and the
 /// [`io::Write`] trait is favored over implementing this trait.
 ///
-/// [`write!`]: ../../std/macro.write.html
+/// [`write!`]: crate::write!
 /// [`io::Write`]: ../../std/io/trait.Write.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Write {
@@ -1058,7 +1058,7 @@ pub trait UpperExp {
 /// assert_eq!(output, "Hello world!");
 /// ```
 ///
-/// [`write!`]: ../../std/macro.write.html
+/// [`write!`]: crate::write!
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
     let mut formatter = Formatter {
@@ -1886,7 +1886,7 @@ impl<'a> Formatter<'a> {
     /// assert_eq!(format!("{:?}", Foo(vec![10, 11])), "{10, 11}");
     /// ```
     ///
-    /// [`format_args!`]: ../../std/macro.format_args.html
+    /// [`format_args!`]: crate::format_args
     ///
     /// In this more complex example, we use [`format_args!`] and `.debug_set()`
     /// to build a list of match arms:
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index a1b0821004b5f..4c62c16f5063c 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1365,6 +1365,8 @@ pub(crate) mod builtin {
     }
 
     /// Attribute macro applied to a static to register it as a global allocator.
+    ///
+    /// See also [`std::alloc::GlobalAlloc`](../std/alloc/trait.GlobalAlloc.html).
     #[stable(feature = "global_allocator", since = "1.28.0")]
     #[allow_internal_unstable(rustc_attrs)]
     #[rustc_builtin_macro]
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index e213963d25046..63de87128340f 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -623,19 +623,27 @@ impl fmt::Display for SocketAddrV6 {
         // Fast path: if there's no alignment stuff, write to the output
         // buffer directly
         if f.precision().is_none() && f.width().is_none() {
-            write!(f, "[{}]:{}", self.ip(), self.port())
+            match self.scope_id() {
+                0 => write!(f, "[{}]:{}", self.ip(), self.port()),
+                scope_id => write!(f, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
+            }
         } else {
             const IPV6_SOCKET_BUF_LEN: usize = (4 * 8)  // The address
             + 7  // The colon separators
             + 2  // The brackets
+            + 1 + 10 // The scope id
             + 1 + 5; // The port
 
             let mut buf = [0; IPV6_SOCKET_BUF_LEN];
             let mut buf_slice = &mut buf[..];
 
+            match self.scope_id() {
+                0 => write!(buf_slice, "[{}]:{}", self.ip(), self.port()),
+                scope_id => write!(buf_slice, "[{}%{}]:{}", self.ip(), scope_id, self.port()),
+            }
             // Unwrap is fine because writing to a sufficiently-sized
             // buffer is infallible
-            write!(buf_slice, "[{}]:{}", self.ip(), self.port()).unwrap();
+            .unwrap();
             let len = IPV6_SOCKET_BUF_LEN - buf_slice.len();
 
             // This unsafe is OK because we know what is being written to the buffer
diff --git a/library/std/src/net/addr/tests.rs b/library/std/src/net/addr/tests.rs
index cee9087e13b32..43f965de25e65 100644
--- a/library/std/src/net/addr/tests.rs
+++ b/library/std/src/net/addr/tests.rs
@@ -178,13 +178,21 @@ fn socket_v4_to_str() {
 
 #[test]
 fn socket_v6_to_str() {
-    let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53".parse().unwrap();
+    let mut socket = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53, 0, 0);
 
     assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1]:53");
     assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1]:53    ");
     assert_eq!(format!("{:>24}", socket), "    [2a02:6b8:0:1::1]:53");
     assert_eq!(format!("{:^24}", socket), "  [2a02:6b8:0:1::1]:53  ");
     assert_eq!(format!("{:.15}", socket), "[2a02:6b8:0:1::");
+
+    socket.set_scope_id(5);
+
+    assert_eq!(format!("{}", socket), "[2a02:6b8:0:1::1%5]:53");
+    assert_eq!(format!("{:<24}", socket), "[2a02:6b8:0:1::1%5]:53  ");
+    assert_eq!(format!("{:>24}", socket), "  [2a02:6b8:0:1::1%5]:53");
+    assert_eq!(format!("{:^24}", socket), " [2a02:6b8:0:1::1%5]:53 ");
+    assert_eq!(format!("{:.18}", socket), "[2a02:6b8:0:1::1%5");
 }
 
 #[test]
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 6856cd338cfad..c87476d8f58b8 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -477,7 +477,7 @@ impl<'a> Builder<'a> {
                 install::Src,
                 install::Rustc
             ),
-            Kind::Run => describe!(run::ExpandYamlAnchors,),
+            Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest,),
         }
     }
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c846662fd5126..857e06d846de4 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -46,7 +46,7 @@ pub fn pkgname(builder: &Builder<'_>, component: &str) -> String {
     }
 }
 
-fn distdir(builder: &Builder<'_>) -> PathBuf {
+pub(crate) fn distdir(builder: &Builder<'_>) -> PathBuf {
     builder.out.join("dist")
 }
 
@@ -2371,6 +2371,7 @@ impl Step for HashSign {
         cmd.arg(addr);
         cmd.arg(&builder.config.channel);
         cmd.arg(&builder.src);
+        cmd.env("BUILD_MANIFEST_LEGACY", "1");
 
         builder.create_dir(&distdir(builder));
 
diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs
index ba593cadbad81..80c093e713eff 100644
--- a/src/bootstrap/run.rs
+++ b/src/bootstrap/run.rs
@@ -1,5 +1,7 @@
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
+use crate::dist::distdir;
 use crate::tool::Tool;
+use build_helper::output;
 use std::process::Command;
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -41,3 +43,43 @@ fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool {
     }
     true
 }
+
+#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct BuildManifest;
+
+impl Step for BuildManifest {
+    type Output = ();
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/build-manifest")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(BuildManifest);
+    }
+
+    fn run(self, builder: &Builder<'_>) {
+        // This gets called by `promote-release`
+        // (https://github.com/rust-lang/promote-release).
+        let mut cmd = builder.tool_cmd(Tool::BuildManifest);
+        let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
+            panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
+        });
+        let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
+            panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
+        });
+
+        let today = output(Command::new("date").arg("+%Y-%m-%d"));
+
+        cmd.arg(sign);
+        cmd.arg(distdir(builder));
+        cmd.arg(today.trim());
+        cmd.arg(addr);
+        cmd.arg(&builder.config.channel);
+        cmd.arg(&builder.src);
+
+        builder.create_dir(&distdir(builder));
+        builder.run(&mut cmd);
+    }
+}
diff --git a/src/test/rustdoc-ui/doc-alias-crate-level.rs b/src/test/rustdoc-ui/doc-alias-crate-level.rs
new file mode 100644
index 0000000000000..309d0bc4d4303
--- /dev/null
+++ b/src/test/rustdoc-ui/doc-alias-crate-level.rs
@@ -0,0 +1,6 @@
+#![feature(doc_alias)]
+
+#![doc(alias = "crate-level-not-working")] //~ ERROR
+
+#[doc(alias = "shouldn't work!")] //~ ERROR
+pub fn foo() {}
diff --git a/src/test/rustdoc-ui/doc-alias-crate-level.stderr b/src/test/rustdoc-ui/doc-alias-crate-level.stderr
new file mode 100644
index 0000000000000..fc14266cd714c
--- /dev/null
+++ b/src/test/rustdoc-ui/doc-alias-crate-level.stderr
@@ -0,0 +1,14 @@
+error: '\'' character isn't allowed in `#[doc(alias = "...")]`
+  --> $DIR/doc-alias-crate-level.rs:5:7
+   |
+LL | #[doc(alias = "shouldn't work!")]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute
+  --> $DIR/doc-alias-crate-level.rs:3:8
+   |
+LL | #![doc(alias = "crate-level-not-working")]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
index 809514e8a1c9d..0fc45513cd78a 100644
--- a/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/array-size-in-generic-struct-param.rs:9:48
    |
 LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
@@ -6,7 +6,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/array-size-in-generic-struct-param.rs:20:15
    |
 LL |     arr: [u8; CFG.arr_size],
diff --git a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
index 8bd3b78725957..dd45b6ed278e8 100644
--- a/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
+++ b/src/test/ui/const-generics/array-size-in-generic-struct-param.rs
@@ -8,7 +8,7 @@
 #[allow(dead_code)]
 struct ArithArrayLen<const N: usize>([u32; 0 + N]);
 //[full]~^ ERROR constant expression depends on a generic parameter
-//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 #[derive(PartialEq, Eq)]
 struct Config {
@@ -19,7 +19,7 @@ struct B<const CFG: Config> {
     //[min]~^ ERROR `Config` is forbidden
     arr: [u8; CFG.arr_size],
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial
 }
 
 const C: Config = Config { arr_size: 5 };
diff --git a/src/test/ui/const-generics/const-argument-if-length.full.stderr b/src/test/ui/const-generics/const-argument-if-length.full.stderr
new file mode 100644
index 0000000000000..9b1c1be1aa09b
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-if-length.full.stderr
@@ -0,0 +1,42 @@
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/const-argument-if-length.rs:8:28
+   |
+LL | pub const fn is_zst<T: ?Sized>() -> usize {
+   |                     - this type parameter needs to be `Sized`
+LL |     if std::mem::size_of::<T>() == 0 {
+   |                            ^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/core/src/mem/mod.rs:LL:COL
+   |
+LL | pub const fn size_of<T>() -> usize {
+   |                      - required by this bound in `std::mem::size_of`
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const-argument-if-length.rs:19:15
+   |
+LL |     pad: [u8; is_zst::<T>()],
+   |               ^^^^^^^^^^^^^ referenced constant has errors
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/const-argument-if-length.rs:17:12
+   |
+LL | pub struct AtLeastByte<T: ?Sized> {
+   |                        - this type parameter needs to be `Sized`
+LL |     value: T,
+   |            ^ doesn't have a size known at compile-time
+   |
+   = note: only the last field of a struct may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     value: &T,
+   |            ^
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     value: Box<T>,
+   |            ^^^^ ^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0080, E0277.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/const-argument-if-length.min.stderr b/src/test/ui/const-generics/const-argument-if-length.min.stderr
new file mode 100644
index 0000000000000..c666dce479f65
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-if-length.min.stderr
@@ -0,0 +1,30 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/const-argument-if-length.rs:19:24
+   |
+LL |     pad: [u8; is_zst::<T>()],
+   |                        ^ non-trivial anonymous constants must not depend on the parameter `T`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/const-argument-if-length.rs:17:12
+   |
+LL | pub struct AtLeastByte<T: ?Sized> {
+   |                        - this type parameter needs to be `Sized`
+LL |     value: T,
+   |            ^ doesn't have a size known at compile-time
+   |
+   = note: only the last field of a struct may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     value: &T,
+   |            ^
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     value: Box<T>,
+   |            ^^^^ ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/const-argument-if-length.rs b/src/test/ui/const-generics/const-argument-if-length.rs
new file mode 100644
index 0000000000000..481ff97d68dbe
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-if-length.rs
@@ -0,0 +1,24 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+pub const fn is_zst<T: ?Sized>() -> usize {
+    if std::mem::size_of::<T>() == 0 {
+        //[full]~^ ERROR the size for values of type `T` cannot be known at compilation time
+        1
+    } else {
+        0
+    }
+}
+
+pub struct AtLeastByte<T: ?Sized> {
+    value: T,
+    //~^ ERROR the size for values of type `T` cannot be known at compilation time
+    pad: [u8; is_zst::<T>()],
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+    //[full]~^^ ERROR evaluation of constant value failed
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
index 269710db164b1..4b3235fd08783 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/feature-gate-const_evaluatable_checked.rs:6:33
    |
 LL | type Arr<const N: usize> = [u8; N - 1];
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
index af3090115f24a..d552e0f543080 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
@@ -4,7 +4,7 @@
 #![cfg_attr(min, feature(min_const_generics))]
 
 type Arr<const N: usize> = [u8; N - 1];
-//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
     //[full]~^ ERROR constant expression depends
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
index 3cac604a7b33a..85a15b1e75fdc 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/simple.rs:8:53
    |
 LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
@@ -6,7 +6,7 @@ LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/simple.rs:8:35
    |
 LL | fn test<const N: usize>() -> [u8; N - 1] where [u8; N - 1]: Default {
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
index 042710f13273e..2eac9505624dd 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/simple_fail.rs:7:33
    |
 LL | type Arr<const N: usize> = [u8; N - 1];
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
index b15e0ff183954..637c940f71432 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
@@ -5,7 +5,7 @@
 #![allow(incomplete_features)]
 
 type Arr<const N: usize> = [u8; N - 1]; //[full]~ ERROR evaluation of constant
-//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 fn test<const N: usize>() -> Arr<N> where Arr<N>: Sized {
     todo!()
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr b/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr
new file mode 100644
index 0000000000000..43b42d82d0c45
--- /dev/null
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/generic-function-call-in-array-length.rs:9:29
+   |
+LL | fn bar<const N: usize>() -> [u32; foo(N)] {
+   |                             ^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr b/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr
new file mode 100644
index 0000000000000..e7e968e4c2ad2
--- /dev/null
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.min.stderr
@@ -0,0 +1,18 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/generic-function-call-in-array-length.rs:9:39
+   |
+LL | fn bar<const N: usize>() -> [u32; foo(N)] {
+   |                                       ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/generic-function-call-in-array-length.rs:12:13
+   |
+LL |     [0; foo(N)]
+   |             ^ non-trivial anonymous constants must not depend on the parameter `N`
+   |
+   = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/generic-function-call-in-array-length.rs b/src/test/ui/const-generics/generic-function-call-in-array-length.rs
new file mode 100644
index 0000000000000..c8bbae29343dc
--- /dev/null
+++ b/src/test/ui/const-generics/generic-function-call-in-array-length.rs
@@ -0,0 +1,16 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+const fn foo(n: usize) -> usize { n * 2 }
+
+fn bar<const N: usize>() -> [u32; foo(N)] {
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+    //[full]~^^ ERROR constant expression depends on a generic parameter
+    [0; foo(N)]
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr b/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr
new file mode 100644
index 0000000000000..d311e1c0bae01
--- /dev/null
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/generic-sum-in-array-length.rs:7:45
+   |
+LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
+   |                                             ^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr b/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr
new file mode 100644
index 0000000000000..6f157fbbbbb8a
--- /dev/null
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.min.stderr
@@ -0,0 +1,18 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/generic-sum-in-array-length.rs:7:53
+   |
+LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
+   |                                                     ^ non-trivial anonymous constants must not depend on the parameter `A`
+   |
+   = help: it is currently only allowed to use either `A` or `{ A }` as generic constants
+
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/generic-sum-in-array-length.rs:7:57
+   |
+LL | fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
+   |                                                         ^ non-trivial anonymous constants must not depend on the parameter `B`
+   |
+   = help: it is currently only allowed to use either `B` or `{ B }` as generic constants
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/generic-sum-in-array-length.rs b/src/test/ui/const-generics/generic-sum-in-array-length.rs
new file mode 100644
index 0000000000000..810095b384baa
--- /dev/null
+++ b/src/test/ui/const-generics/generic-sum-in-array-length.rs
@@ -0,0 +1,12 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+fn foo<const A: usize, const B: usize>(bar: [usize; A + B]) {}
+//[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+//[min]~| ERROR generic parameters must not be used inside of non-trivial constant values
+//[full]~^^^ ERROR constant expression depends on a generic parameter
+
+fn main() {}
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr
new file mode 100644
index 0000000000000..a587cb618731a
--- /dev/null
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.full.stderr
@@ -0,0 +1,8 @@
+error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
+  --> $DIR/impl-trait-with-const-arguments.rs:24:20
+   |
+LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
+   |                    ^^^^^^ explicit generic argument not allowed
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr
new file mode 100644
index 0000000000000..a587cb618731a
--- /dev/null
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.min.stderr
@@ -0,0 +1,8 @@
+error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
+  --> $DIR/impl-trait-with-const-arguments.rs:24:20
+   |
+LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
+   |                    ^^^^^^ explicit generic argument not allowed
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs b/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
new file mode 100644
index 0000000000000..a4c75792ee359
--- /dev/null
+++ b/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
@@ -0,0 +1,26 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+trait Usizer {
+    fn m(self) -> usize;
+}
+
+fn f<const N: usize>(u: impl Usizer) -> usize {
+    N + u.m()
+}
+
+struct Usizable;
+
+impl Usizer for Usizable {
+    fn m(self) -> usize {
+        16
+    }
+}
+
+fn main() {
+    assert_eq!(f::<4usize>(Usizable), 20usize);
+//~^ ERROR cannot provide explicit generic arguments when `impl Trait` is used in argument position
+}
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr
new file mode 100644
index 0000000000000..c09d16d0ab05b
--- /dev/null
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:15:8
+   |
+LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
new file mode 100644
index 0000000000000..307db088bf892
--- /dev/null
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
@@ -0,0 +1,19 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:15:44
+   |
+LL |     T: Trait<{std::intrinsics::type_name::<T>()}>
+   |                                            ^ non-trivial anonymous constants must not depend on the parameter `T`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error: `&'static str` is forbidden as the type of a const generic parameter
+  --> $DIR/intrinsics-type_name-as-const-argument.rs:10:22
+   |
+LL | trait Trait<const S: &'static str> {}
+   |                      ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs
new file mode 100644
index 0000000000000..37b6cf4bab92b
--- /dev/null
+++ b/src/test/ui/const-generics/intrinsics-type_name-as-const-argument.rs
@@ -0,0 +1,22 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+#![feature(core_intrinsics)]
+#![feature(const_type_name)]
+
+trait Trait<const S: &'static str> {}
+//[min]~^ ERROR `&'static str` is forbidden as the type of a const generic parameter
+
+struct Bug<T>
+where
+    T: Trait<{std::intrinsics::type_name::<T>()}>
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+    //[full]~^^ ERROR constant expression depends on a generic parameter
+{
+    t: T
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr b/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
index a1b1a095041b3..2c1bc055b28ae 100644
--- a/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
+++ b/src/test/ui/const-generics/issue-61522-array-len-succ.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-61522-array-len-succ.rs:7:45
    |
 LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
@@ -6,7 +6,7 @@ LL | pub struct MyArray<const COUNT: usize>([u8; COUNT + 1]);
    |
    = help: it is currently only allowed to use either `COUNT` or `{ COUNT }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-61522-array-len-succ.rs:12:30
    |
 LL |     fn inner(&self) -> &[u8; COUNT + 1] {
diff --git a/src/test/ui/const-generics/issue-67375.full.stderr b/src/test/ui/const-generics/issue-67375.full.stderr
new file mode 100644
index 0000000000000..e15d65f197e29
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67375.full.stderr
@@ -0,0 +1,21 @@
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/issue-67375.rs:9:12
+   |
+LL |     inner: [(); { [|_: &T| {}; 0].len() }],
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
+
+error[E0392]: parameter `T` is never used
+  --> $DIR/issue-67375.rs:7:12
+   |
+LL | struct Bug<T> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/const-generics/issue-67375.min.stderr b/src/test/ui/const-generics/issue-67375.min.stderr
new file mode 100644
index 0000000000000..b13d9fdab0d96
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67375.min.stderr
@@ -0,0 +1,19 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/issue-67375.rs:9:25
+   |
+LL |     inner: [(); { [|_: &T| {}; 0].len() }],
+   |                         ^ non-trivial anonymous constants must not depend on the parameter `T`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error[E0392]: parameter `T` is never used
+  --> $DIR/issue-67375.rs:7:12
+   |
+LL | struct Bug<T> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/const-generics/issue-67375.rs b/src/test/ui/const-generics/issue-67375.rs
new file mode 100644
index 0000000000000..994ec92cfb501
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67375.rs
@@ -0,0 +1,15 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+struct Bug<T> {
+    //~^ ERROR parameter `T` is never used
+    inner: [(); { [|_: &T| {}; 0].len() }],
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+    //[full]~^^ WARN cannot use constants which depend on generic parameters in types
+    //[full]~^^^ WARN this was previously accepted by the compiler
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-67945-1.full.stderr b/src/test/ui/const-generics/issue-67945-1.full.stderr
new file mode 100644
index 0000000000000..e79c4f5374e1a
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-1.full.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-67945-1.rs:14:20
+   |
+LL | struct Bug<S> {
+   |            - this type parameter
+...
+LL |         let x: S = MaybeUninit::uninit();
+   |                -   ^^^^^^^^^^^^^^^^^^^^^ expected type parameter `S`, found union `MaybeUninit`
+   |                |
+   |                expected due to this
+   |
+   = note: expected type parameter `S`
+                       found union `MaybeUninit<_>`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-1.rs:11:12
+   |
+LL | struct Bug<S> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0392.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/issue-67945-1.min.stderr b/src/test/ui/const-generics/issue-67945-1.min.stderr
new file mode 100644
index 0000000000000..949b5da5920b1
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-1.min.stderr
@@ -0,0 +1,27 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/issue-67945-1.rs:14:16
+   |
+LL |         let x: S = MaybeUninit::uninit();
+   |                ^ non-trivial anonymous constants must not depend on the parameter `S`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/issue-67945-1.rs:17:45
+   |
+LL |         let b = &*(&x as *const _ as *const S);
+   |                                             ^ non-trivial anonymous constants must not depend on the parameter `S`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-1.rs:11:12
+   |
+LL | struct Bug<S> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/const-generics/issue-67945-1.rs b/src/test/ui/const-generics/issue-67945-1.rs
new file mode 100644
index 0000000000000..d1a83e978d1b8
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-1.rs
@@ -0,0 +1,23 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+use std::marker::PhantomData;
+
+use std::mem::{self, MaybeUninit};
+
+struct Bug<S> {
+    //~^ ERROR parameter `S` is never used
+    A: [(); {
+        let x: S = MaybeUninit::uninit();
+        //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+        //[full]~^^ ERROR mismatched types
+        let b = &*(&x as *const _ as *const S);
+        //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+        0
+    }],
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-67945-2.full.stderr b/src/test/ui/const-generics/issue-67945-2.full.stderr
new file mode 100644
index 0000000000000..2f54b802df8a4
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-2.full.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-67945-2.rs:12:20
+   |
+LL | struct Bug<S> {
+   |            - this type parameter
+...
+LL |         let x: S = MaybeUninit::uninit();
+   |                -   ^^^^^^^^^^^^^^^^^^^^^ expected type parameter `S`, found union `MaybeUninit`
+   |                |
+   |                expected due to this
+   |
+   = note: expected type parameter `S`
+                       found union `MaybeUninit<_>`
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-2.rs:9:12
+   |
+LL | struct Bug<S> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0392.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/issue-67945-2.min.stderr b/src/test/ui/const-generics/issue-67945-2.min.stderr
new file mode 100644
index 0000000000000..ed445b3e8f790
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-2.min.stderr
@@ -0,0 +1,27 @@
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/issue-67945-2.rs:12:16
+   |
+LL |         let x: S = MaybeUninit::uninit();
+   |                ^ non-trivial anonymous constants must not depend on the parameter `S`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error: generic parameters must not be used inside of non-trivial constant values
+  --> $DIR/issue-67945-2.rs:15:45
+   |
+LL |         let b = &*(&x as *const _ as *const S);
+   |                                             ^ non-trivial anonymous constants must not depend on the parameter `S`
+   |
+   = note: type parameters are currently not permitted in anonymous constants
+
+error[E0392]: parameter `S` is never used
+  --> $DIR/issue-67945-2.rs:9:12
+   |
+LL | struct Bug<S> {
+   |            ^ unused parameter
+   |
+   = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/src/test/ui/const-generics/issue-67945-2.rs b/src/test/ui/const-generics/issue-67945-2.rs
new file mode 100644
index 0000000000000..7f789297df034
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-2.rs
@@ -0,0 +1,21 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+use std::mem::MaybeUninit;
+
+struct Bug<S> {
+    //~^ ERROR parameter `S` is never used
+    A: [(); {
+        let x: S = MaybeUninit::uninit();
+        //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+        //[full]~^^ ERROR mismatched types
+        let b = &*(&x as *const _ as *const S);
+        //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+        0
+    }],
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-67945-3.full.stderr b/src/test/ui/const-generics/issue-67945-3.full.stderr
new file mode 100644
index 0000000000000..c33b88588c0d0
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-3.full.stderr
@@ -0,0 +1,16 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-67945-3.rs:8:8
+   |
+LL |       A: [(); {
+   |  ________^
+LL | |
+LL | |         let x: Option<Box<Self>> = None;
+LL | |
+LL | |         0
+LL | |     }],
+   | |______^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issue-67945-3.min.stderr b/src/test/ui/const-generics/issue-67945-3.min.stderr
new file mode 100644
index 0000000000000..9c6e101ece868
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-3.min.stderr
@@ -0,0 +1,8 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+  --> $DIR/issue-67945-3.rs:10:27
+   |
+LL |         let x: Option<Box<Self>> = None;
+   |                           ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issue-67945-3.rs b/src/test/ui/const-generics/issue-67945-3.rs
new file mode 100644
index 0000000000000..bca079101e2b3
--- /dev/null
+++ b/src/test/ui/const-generics/issue-67945-3.rs
@@ -0,0 +1,17 @@
+// revisions: full min
+
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+struct Bug<S: ?Sized> {
+    A: [(); {
+        //[full]~^ ERROR constant expression depends on a generic parameter
+        let x: Option<Box<Self>> = None;
+        //[min]~^ ERROR generic `Self` types are currently not permitted in anonymous constants
+        0
+    }],
+    B: S
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-61747.min.stderr b/src/test/ui/const-generics/issues/issue-61747.min.stderr
index 2061b6c55bb7b..fdd9a569748e2 100644
--- a/src/test/ui/const-generics/issues/issue-61747.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61747.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-61747.rs:8:30
    |
 LL |     fn successor() -> Const<{C + 1}> {
diff --git a/src/test/ui/const-generics/issues/issue-61935.min.stderr b/src/test/ui/const-generics/issues/issue-61935.min.stderr
index e5715ec658c5c..f461a31eeae3a 100644
--- a/src/test/ui/const-generics/issues/issue-61935.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-61935.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-61935.rs:10:23
    |
 LL |         Self:FooImpl<{N==0}>
diff --git a/src/test/ui/const-generics/issues/issue-61935.rs b/src/test/ui/const-generics/issues/issue-61935.rs
index 64257da030943..a181a8dabe5aa 100644
--- a/src/test/ui/const-generics/issues/issue-61935.rs
+++ b/src/test/ui/const-generics/issues/issue-61935.rs
@@ -9,7 +9,7 @@ impl<const N: usize> Foo for [(); N]
     where
         Self:FooImpl<{N==0}>
 //[full]~^ERROR constant expression depends on a generic parameter
-//[min]~^^ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^^ERROR generic parameters must not be used inside of non-trivial constant values
 {}
 
 trait FooImpl<const IS_ZERO: bool>{}
diff --git a/src/test/ui/const-generics/issues/issue-62220.min.stderr b/src/test/ui/const-generics/issues/issue-62220.min.stderr
index 943b689bf61af..84975e8f3be6b 100644
--- a/src/test/ui/const-generics/issues/issue-62220.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62220.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-62220.rs:8:59
    |
 LL | pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
diff --git a/src/test/ui/const-generics/issues/issue-62220.rs b/src/test/ui/const-generics/issues/issue-62220.rs
index acb13ad1170f2..5694dc6d04da1 100644
--- a/src/test/ui/const-generics/issues/issue-62220.rs
+++ b/src/test/ui/const-generics/issues/issue-62220.rs
@@ -6,7 +6,7 @@
 pub struct Vector<T, const N: usize>([T; N]);
 
 pub type TruncatedVector<T, const N: usize> = Vector<T, { N - 1 }>;
-//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 impl<T, const N: usize> Vector<T, { N }> {
     /// Drop the last component and return the vector with one fewer dimension.
diff --git a/src/test/ui/const-generics/issues/issue-62456.min.stderr b/src/test/ui/const-generics/issues/issue-62456.min.stderr
index 335f0ead27871..f94ba8c0c9b87 100644
--- a/src/test/ui/const-generics/issues/issue-62456.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-62456.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-62456.rs:7:20
    |
 LL |     let _ = [0u64; N + 1];
diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs
index c96868c00a3d6..338ec42799d17 100644
--- a/src/test/ui/const-generics/issues/issue-62456.rs
+++ b/src/test/ui/const-generics/issues/issue-62456.rs
@@ -6,7 +6,7 @@
 fn foo<const N: usize>() {
     let _ = [0u64; N + 1];
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-64494.min.stderr b/src/test/ui/const-generics/issues/issue-64494.min.stderr
index 07822f86f524b..f712171bbac61 100644
--- a/src/test/ui/const-generics/issues/issue-64494.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-64494.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-64494.rs:16:38
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
@@ -6,7 +6,7 @@ LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
    |
    = note: type parameters are currently not permitted in anonymous constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-64494.rs:19:38
    |
 LL | impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
diff --git a/src/test/ui/const-generics/issues/issue-64494.rs b/src/test/ui/const-generics/issues/issue-64494.rs
index 3b598a415223a..b62ebf846d5b1 100644
--- a/src/test/ui/const-generics/issues/issue-64494.rs
+++ b/src/test/ui/const-generics/issues/issue-64494.rs
@@ -15,10 +15,10 @@ impl True for Is<{true}> {}
 
 impl<T: Foo> MyTrait for T where Is<{T::VAL == 5}>: True {}
 //[full]~^ ERROR constant expression depends on a generic parameter
-//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 impl<T: Foo> MyTrait for T where Is<{T::VAL == 6}>: True {}
 //[full]~^ ERROR constant expression depends on a generic parameter
-//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 //[min]~| ERROR conflicting implementations of trait `MyTrait`
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-66205.min.stderr b/src/test/ui/const-generics/issues/issue-66205.min.stderr
index 86709c389b623..a18126ccfef6d 100644
--- a/src/test/ui/const-generics/issues/issue-66205.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-66205.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-66205.rs:8:14
    |
 LL |     fact::<{ N - 1 }>();
diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs
index e115eff356a7f..668f49852e1ef 100644
--- a/src/test/ui/const-generics/issues/issue-66205.rs
+++ b/src/test/ui/const-generics/issues/issue-66205.rs
@@ -7,7 +7,7 @@
 fn fact<const N: usize>() {
     fact::<{ N - 1 }>();
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 }
 
 fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr
index 68f1733decb93..ba378de415654 100644
--- a/src/test/ui/const-generics/issues/issue-67739.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-67739.rs:12:30
    |
 LL |         [0u8; mem::size_of::<Self::Associated>()];
diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs
index 72bf3ee9602fc..296e4d423c48a 100644
--- a/src/test/ui/const-generics/issues/issue-67739.rs
+++ b/src/test/ui/const-generics/issues/issue-67739.rs
@@ -11,7 +11,7 @@ pub trait Trait {
     fn associated_size(&self) -> usize {
         [0u8; mem::size_of::<Self::Associated>()];
         //[full]~^ ERROR constant expression depends on a generic parameter
-        //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+        //[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
         0
     }
 }
diff --git a/src/test/ui/const-generics/issues/issue-68366.min.stderr b/src/test/ui/const-generics/issues/issue-68366.min.stderr
index 8d34bdc6ea0c8..73d6fec6f9b56 100644
--- a/src/test/ui/const-generics/issues/issue-68366.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68366.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-68366.rs:12:37
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
diff --git a/src/test/ui/const-generics/issues/issue-68366.rs b/src/test/ui/const-generics/issues/issue-68366.rs
index 819fcaffea18c..ac313eb3b2ff3 100644
--- a/src/test/ui/const-generics/issues/issue-68366.rs
+++ b/src/test/ui/const-generics/issues/issue-68366.rs
@@ -11,7 +11,7 @@ struct Collatz<const N: Option<usize>>;
 
 impl <const N: usize> Collatz<{Some(N)}> {}
 //~^ ERROR the const parameter
-//[min]~^^ generic parameters must not be used inside of non trivial constant values
+//[min]~^^ generic parameters must not be used inside of non-trivial constant values
 
 struct Foo;
 
diff --git a/src/test/ui/const-generics/issues/issue-68977.min.stderr b/src/test/ui/const-generics/issues/issue-68977.min.stderr
index 5b2137b244cb2..59d2be3ce4b42 100644
--- a/src/test/ui/const-generics/issues/issue-68977.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-68977.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-68977.rs:29:17
    |
 LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
@@ -6,7 +6,7 @@ LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
    |
    = help: it is currently only allowed to use either `INT_BITS` or `{ INT_BITS }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-68977.rs:29:28
    |
 LL |     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
diff --git a/src/test/ui/const-generics/issues/issue-68977.rs b/src/test/ui/const-generics/issues/issue-68977.rs
index 02e634efec3e7..49b305a5a783f 100644
--- a/src/test/ui/const-generics/issues/issue-68977.rs
+++ b/src/test/ui/const-generics/issues/issue-68977.rs
@@ -27,8 +27,8 @@ fxp_storage_impls! {
 
 type FxpStorageHelper<const INT_BITS: u8, const FRAC_BITS: u8> =
     PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>;
-    //[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
-    //[min]~| ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~^ ERROR generic parameters must not be used inside of non-trivial constant values
+    //[min]~| ERROR generic parameters must not be used inside of non-trivial constant values
 
 struct Fxp<const INT_BITS: u8, const FRAC_BITS: u8>
 where
diff --git a/src/test/ui/const-generics/issues/issue-72787.min.stderr b/src/test/ui/const-generics/issues/issue-72787.min.stderr
index d3e9887fe209c..a4c80b1d8c01e 100644
--- a/src/test/ui/const-generics/issues/issue-72787.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-72787.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-72787.rs:11:17
    |
 LL |     Condition<{ LHS <= RHS }>: True
@@ -6,7 +6,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    |
    = help: it is currently only allowed to use either `LHS` or `{ LHS }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-72787.rs:11:24
    |
 LL |     Condition<{ LHS <= RHS }>: True
@@ -14,7 +14,7 @@ LL |     Condition<{ LHS <= RHS }>: True
    |
    = help: it is currently only allowed to use either `RHS` or `{ RHS }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-72787.rs:26:25
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
@@ -22,7 +22,7 @@ LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
    |
    = help: it is currently only allowed to use either `I` or `{ I }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-72787.rs:26:36
    |
 LL |     IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs
index 45c20191c8848..779c1d2950e4d 100644
--- a/src/test/ui/const-generics/issues/issue-72787.rs
+++ b/src/test/ui/const-generics/issues/issue-72787.rs
@@ -10,8 +10,8 @@ pub trait True {}
 impl<const LHS: u32, const RHS: u32> True for IsLessOrEqual<LHS, RHS> where
     Condition<{ LHS <= RHS }>: True
 //[full]~^ Error constant expression depends on a generic parameter
-//[min]~^^ Error generic parameters must not be used inside of non trivial constant values
-//[min]~| Error generic parameters must not be used inside of non trivial constant values
+//[min]~^^ Error generic parameters must not be used inside of non-trivial constant values
+//[min]~| Error generic parameters must not be used inside of non-trivial constant values
 {
 }
 impl True for Condition<true> {}
@@ -28,8 +28,8 @@ where
 //[full]~| constant expression depends on a generic parameter
 //[full]~| constant expression depends on a generic parameter
 //[full]~| constant expression depends on a generic parameter
-//[min]~^^^^^ Error generic parameters must not be used inside of non trivial constant values
-//[min]~| Error generic parameters must not be used inside of non trivial constant values
+//[min]~^^^^^ Error generic parameters must not be used inside of non-trivial constant values
+//[min]~| Error generic parameters must not be used inside of non-trivial constant values
     // Condition<{ 8 - I <= 8 - J }>: True,
 {
     fn print() {
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
index 48a1f0bd19c0a..afc14c7dcff57 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-72819-generic-in-const-eval.rs:9:17
    |
 LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
index b653b91d99d14..65c7f00a72ae5 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
@@ -8,7 +8,7 @@
 struct Arr<const N: usize>
 where Assert::<{N < usize::max_value() / 2}>: IsTrue,
 //[full]~^ ERROR constant expression depends on a generic parameter
-//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+//[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
 {
 }
 
diff --git a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
index a39495e0b2db0..0db948d0a45db 100644
--- a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
+++ b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-76701-ty-param-in-const.rs:6:46
    |
 LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
@@ -6,7 +6,7 @@ LL | fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
    |
    = note: type parameters are currently not permitted in anonymous constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/issue-76701-ty-param-in-const.rs:12:42
    |
 LL | fn const_param<const N: usize>() -> [u8; N + 1] {
diff --git a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
index 9252b592360d3..3c5bfb03f0801 100644
--- a/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
+++ b/src/test/ui/const-generics/issues/issue-76701-ty-param-in-const.rs
@@ -5,13 +5,13 @@
 
 fn ty_param<T>() -> [u8; std::mem::size_of::<T>()] {
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
     todo!()
 }
 
 fn const_param<const N: usize>() -> [u8; N + 1] {
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial constant values
     todo!()
 }
 
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
index f9cb0d2829d6e..c6380f6394d01 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-expression.rs
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs
@@ -7,19 +7,19 @@ fn ok<const M: usize>() -> [u8; M] {
 }
 
 struct Break0<const N: usize>([u8; { N + 1 }]);
-//~^ ERROR generic parameters must not be used inside of non trivial constant values
+//~^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 struct Break1<const N: usize>([u8; { { N } }]);
-//~^ ERROR generic parameters must not be used inside of non trivial constant values
+//~^ ERROR generic parameters must not be used inside of non-trivial constant values
 
 fn break2<const N: usize>() {
     let _: [u8; N + 1];
-    //~^ ERROR generic parameters must not be used inside of non trivial constant values
+    //~^ ERROR generic parameters must not be used inside of non-trivial constant values
 }
 
 fn break3<const N: usize>() {
     let _ = [0; N + 1];
-    //~^ ERROR generic parameters must not be used inside of non trivial constant values
+    //~^ ERROR generic parameters must not be used inside of non-trivial constant values
 }
 
 trait Foo {
diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
index baed8d13f00f1..d8897f53d7f74 100644
--- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
+++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/complex-expression.rs:9:38
    |
 LL | struct Break0<const N: usize>([u8; { N + 1 }]);
@@ -6,7 +6,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/complex-expression.rs:12:40
    |
 LL | struct Break1<const N: usize>([u8; { { N } }]);
@@ -14,7 +14,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/complex-expression.rs:16:17
    |
 LL |     let _: [u8; N + 1];
@@ -22,7 +22,7 @@ LL |     let _: [u8; N + 1];
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/complex-expression.rs:21:17
    |
 LL |     let _ = [0; N + 1];
diff --git a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
index edb77a8743061..7dc81bf45af9a 100644
--- a/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
+++ b/src/test/ui/const-generics/min_const_generics/self-ty-in-const-1.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/self-ty-in-const-1.rs:4:41
    |
 LL |     fn t1() -> [u8; std::mem::size_of::<Self>()];
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
new file mode 100644
index 0000000000000..0ef17109bed40
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.rs
@@ -0,0 +1,8 @@
+#![feature(min_const_generics)]
+
+fn a<const X: &'static [u32]>() {}
+//~^ ERROR `&'static [u32]` is forbidden as the type of a const generic parameter
+
+fn main() {
+    a::<{&[]}>();
+}
diff --git a/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
new file mode 100644
index 0000000000000..cc32d8a67fed0
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/static-reference-array-const-param.stderr
@@ -0,0 +1,11 @@
+error: `&'static [u32]` is forbidden as the type of a const generic parameter
+  --> $DIR/static-reference-array-const-param.rs:3:15
+   |
+LL | fn a<const X: &'static [u32]>() {}
+   |               ^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
new file mode 100644
index 0000000000000..dfa1ece2f3657
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
@@ -0,0 +1,12 @@
+#![feature(min_const_generics)]
+
+struct Const<const P: &'static ()>;
+//~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
+
+fn main() {
+    const A: &'static () = unsafe {
+        std::mem::transmute(10 as *const ())
+    };
+
+    let _ = Const::<{A}>;
+}
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
new file mode 100644
index 0000000000000..063120ad074a0
--- /dev/null
+++ b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
@@ -0,0 +1,11 @@
+error: `&'static ()` is forbidden as the type of a const generic parameter
+  --> $DIR/transmute-const-param-static-reference.rs:3:23
+   |
+LL | struct Const<const P: &'static ()>;
+   |                       ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
index e545ae8571f67..0dd591d891f2b 100644
--- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
+++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.min.stderr
@@ -6,7 +6,7 @@ LL | struct Bar<T = [u8; N], const N: usize>(T);
    |
    = note: using type defaults and const parameters in the same parameter list is currently not permitted
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:7:44
    |
 LL | struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
diff --git a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
index e52773c78dbd3..b9d74850f37d6 100644
--- a/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
+++ b/src/test/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs
@@ -6,7 +6,7 @@
 
 struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
 //[full]~^ ERROR constant values inside of type parameter defaults
-//[min]~^^ ERROR generic parameters must not be used inside of non trivial
+//[min]~^^ ERROR generic parameters must not be used inside of non-trivial
 
 // FIXME(const_generics:defaults): We still don't know how to we deal with type defaults.
 struct Bar<T = [u8; N], const N: usize>(T);
diff --git a/src/test/ui/const-generics/wf-misc.min.stderr b/src/test/ui/const-generics/wf-misc.min.stderr
index f2acb8fc06e93..1c52d60174997 100644
--- a/src/test/ui/const-generics/wf-misc.min.stderr
+++ b/src/test/ui/const-generics/wf-misc.min.stderr
@@ -1,4 +1,4 @@
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/wf-misc.rs:9:17
    |
 LL |     let _: [u8; N + 1];
@@ -6,7 +6,7 @@ LL |     let _: [u8; N + 1];
    |
    = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
 
-error: generic parameters must not be used inside of non trivial constant values
+error: generic parameters must not be used inside of non-trivial constant values
   --> $DIR/wf-misc.rs:17:21
    |
 LL |     let _: Const::<{N + 1}>;
diff --git a/src/test/ui/const-generics/wf-misc.rs b/src/test/ui/const-generics/wf-misc.rs
index e6f7a9963e8f1..f8c41404c467b 100644
--- a/src/test/ui/const-generics/wf-misc.rs
+++ b/src/test/ui/const-generics/wf-misc.rs
@@ -8,7 +8,7 @@
 pub fn arr_len<const N: usize>() {
     let _: [u8; N + 1];
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial
 }
 
 struct Const<const N: usize>;
@@ -16,7 +16,7 @@ struct Const<const N: usize>;
 pub fn func_call<const N: usize>() {
     let _: Const::<{N + 1}>;
     //[full]~^ ERROR constant expression depends on a generic parameter
-    //[min]~^^ ERROR generic parameters must not be used inside of non trivial
+    //[min]~^^ ERROR generic parameters must not be used inside of non-trivial
 }
 
 fn main() {}
diff --git a/src/test/ui/consts/const-eval/unwind-abort.rs b/src/test/ui/consts/const-eval/unwind-abort.rs
new file mode 100644
index 0000000000000..b8b95dea1e770
--- /dev/null
+++ b/src/test/ui/consts/const-eval/unwind-abort.rs
@@ -0,0 +1,13 @@
+#![feature(unwind_attributes, const_panic)]
+
+#[unwind(aborts)]
+const fn foo() {
+    panic!() //~ evaluation of constant value failed
+}
+
+const _: () = foo(); //~ any use of this value will cause an error
+// Ensure that the CTFE engine handles calls to `#[unwind(aborts)]` gracefully
+
+fn main() {
+    let _ = foo();
+}
diff --git a/src/test/ui/consts/const-eval/unwind-abort.stderr b/src/test/ui/consts/const-eval/unwind-abort.stderr
new file mode 100644
index 0000000000000..084beb19eb934
--- /dev/null
+++ b/src/test/ui/consts/const-eval/unwind-abort.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/unwind-abort.rs:5:5
+   |
+LL |     panic!()
+   |     ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:5:5
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: any use of this value will cause an error
+  --> $DIR/unwind-abort.rs:8:15
+   |
+LL | const _: () = foo();
+   | --------------^^^^^-
+   |               |
+   |               referenced constant has errors
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/unwind-abort.rs b/src/test/ui/consts/unwind-abort.rs
new file mode 100644
index 0000000000000..f9011f908a75e
--- /dev/null
+++ b/src/test/ui/consts/unwind-abort.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(unwind_attributes, const_panic)]
+
+// `#[unwind(aborts)]` is okay for a `const fn`. We don't unwind in const-eval anyways.
+#[unwind(aborts)]
+const fn foo() {
+    panic!()
+}
+
+const fn bar() {
+    foo();
+}
+
+fn main() {
+    bar();
+}
diff --git a/src/test/ui/doc-alias-crate-level.rs b/src/test/ui/doc-alias-crate-level.rs
new file mode 100644
index 0000000000000..b1b17f2de8adf
--- /dev/null
+++ b/src/test/ui/doc-alias-crate-level.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Zdeduplicate-diagnostics=no
+
+#![feature(doc_alias)]
+
+#![crate_type = "lib"]
+
+#![doc(alias = "shouldn't work!")] //~ ERROR
diff --git a/src/test/ui/doc-alias-crate-level.stderr b/src/test/ui/doc-alias-crate-level.stderr
new file mode 100644
index 0000000000000..45756d6a04bd0
--- /dev/null
+++ b/src/test/ui/doc-alias-crate-level.stderr
@@ -0,0 +1,8 @@
+error: '\'' character isn't allowed in `#[doc(alias = "...")]`
+  --> $DIR/doc-alias-crate-level.rs:7:8
+   |
+LL | #![doc(alias = "shouldn't work!")]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs
index 3ac8ba5232de7..6404b2c3115cb 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs
@@ -1,3 +1,6 @@
+//~ NOTE: not an `extern crate` item
+//~^ NOTE: not a function or static
+//~^^ NOTE: not a function or closure
 // This is testing whether various builtin attributes signals an
 // error or warning when put in "weird" places.
 //
@@ -7,9 +10,25 @@
 
 // ignore-tidy-linelength
 
-// Crate-level is accepted, though it is almost certainly unused?
+#![macro_export]
+//~^ ERROR: `macro_export` attribute cannot be used at crate level
+#![main]
+//~^ ERROR: `main` attribute cannot be used at crate level
+#![start]
+//~^ ERROR: `start` attribute cannot be used at crate level
+#![repr()]
+//~^ ERROR: `repr` attribute cannot be used at crate level
+#![path = "3800"]
+//~^ ERROR: `path` attribute cannot be used at crate level
+#![automatically_derived]
+//~^ ERROR: `automatically_derived` attribute cannot be used at crate level
+#![no_mangle]
+#![no_link]
+//~^ ERROR: attribute should be applied to an `extern crate` item
+#![export_name = "2200"]
+//~^ ERROR: attribute should be applied to a function or static
 #![inline]
-
+//~^ ERROR: attribute should be applied to function or closure
 #[inline]
 //~^ ERROR attribute should be applied to function or closure
 mod inline {
@@ -88,4 +107,40 @@ mod export_name {
     //~| NOTE not a function or static
 }
 
+#[main]
+//~^ ERROR: `main` attribute can only be used on functions
+mod main {
+    mod inner { #![main] }
+    //~^ ERROR: `main` attribute can only be used on functions
+
+    // for `fn f()` case, see feature-gate-main.rs
+
+    #[main] struct S;
+    //~^ ERROR: `main` attribute can only be used on functions
+
+    #[main] type T = S;
+    //~^ ERROR: `main` attribute can only be used on functions
+
+    #[main] impl S { }
+    //~^ ERROR: `main` attribute can only be used on functions
+}
+
+#[start]
+//~^ ERROR: `start` attribute can only be used on functions
+mod start {
+    mod inner { #![start] }
+    //~^ ERROR: `start` attribute can only be used on functions
+
+    // for `fn f()` case, see feature-gate-start.rs
+
+    #[start] struct S;
+    //~^ ERROR: `start` attribute can only be used on functions
+
+    #[start] type T = S;
+    //~^ ERROR: `start` attribute can only be used on functions
+
+    #[start] impl S { }
+    //~^ ERROR: `start` attribute can only be used on functions
+}
+
 fn main() {}
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.stderr
index c9255d2be129b..3ca1bd2ea7e48 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -1,5 +1,5 @@
 error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:22:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:41:5
    |
 LL |     #[inline = "2100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
@@ -8,8 +8,68 @@ LL |     #[inline = "2100"] 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!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
+error: `main` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:1
+   |
+LL | #[main]
+   | ^^^^^^^
+
+error: `main` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:17
+   |
+LL |     mod inner { #![main] }
+   |                 ^^^^^^^^
+
+error: `main` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:118:5
+   |
+LL |     #[main] struct S;
+   |     ^^^^^^^
+
+error: `main` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:5
+   |
+LL |     #[main] type T = S;
+   |     ^^^^^^^
+
+error: `main` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:124:5
+   |
+LL |     #[main] impl S { }
+   |     ^^^^^^^
+
+error: `start` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:128:1
+   |
+LL | #[start]
+   | ^^^^^^^^
+
+error: `start` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:17
+   |
+LL |     mod inner { #![start] }
+   |                 ^^^^^^^^^
+
+error: `start` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:136:5
+   |
+LL |     #[start] struct S;
+   |     ^^^^^^^^
+
+error: `start` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:139:5
+   |
+LL |     #[start] type T = S;
+   |     ^^^^^^^^
+
+error: `start` attribute can only be used on functions
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:142:5
+   |
+LL |     #[start] impl S { }
+   |     ^^^^^^^^
+
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:13:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1
    |
 LL |   #[inline]
    |   ^^^^^^^^^
@@ -24,7 +84,7 @@ LL | | }
    | |_- not a function or closure
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:41:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:60:1
    |
 LL |   #[no_link]
    |   ^^^^^^^^^^
@@ -39,7 +99,7 @@ LL | | }
    | |_- not an `extern crate` item
 
 error: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:1
    |
 LL |   #[export_name = "2200"]
    |   ^^^^^^^^^^^^^^^^^^^^^^^
@@ -53,84 +113,138 @@ LL | |
 LL | | }
    | |_- not a function or static
 
+error: attribute should be applied to an `extern crate` item
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:26:1
+   |
+LL | #![no_link]
+   | ^^^^^^^^^^^
+
+error: attribute should be applied to a function or static
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:28:1
+   |
+LL | #![export_name = "2200"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0518]: attribute should be applied to function or closure
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1
+   |
+LL | #![inline]
+   | ^^^^^^^^^^
+
+error: `macro_export` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:13:1
+   |
+LL | #![macro_export]
+   | ^^^^^^^^^^^^^^^^
+
+error: `main` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:15:1
+   |
+LL | #![main]
+   | ^^^^^^^^
+
+error: `start` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1
+   |
+LL | #![start]
+   | ^^^^^^^^^
+
+error: `repr` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:19:1
+   |
+LL | #![repr()]
+   | ^^^^^^^^^^
+
+error: `path` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1
+   |
+LL | #![path = "3800"]
+   | ^^^^^^^^^^^^^^^^^
+
+error: `automatically_derived` attribute cannot be used at crate level
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1
+   |
+LL | #![automatically_derived]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:18:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:17
    |
 LL |     mod inner { #![inline] }
    |     ------------^^^^^^^^^^-- not a function or closure
 
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:28:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:47:5
    |
 LL |     #[inline] struct S;
    |     ^^^^^^^^^ --------- not a function or closure
 
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5
    |
 LL |     #[inline] type T = S;
    |     ^^^^^^^^^ ----------- not a function or closure
 
 error[E0518]: attribute should be applied to function or closure
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:5
    |
 LL |     #[inline] impl S { }
    |     ^^^^^^^^^ ---------- not a function or closure
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:65:17
    |
 LL |     mod inner { #![no_link] }
    |     ------------^^^^^^^^^^^-- not an `extern crate` item
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:50:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:69:5
    |
 LL |     #[no_link] fn f() { }
    |     ^^^^^^^^^^ ---------- not an `extern crate` item
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5
    |
 LL |     #[no_link] struct S;
    |     ^^^^^^^^^^ --------- not an `extern crate` item
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:58:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5
    |
 LL |     #[no_link]type T = S;
    |     ^^^^^^^^^^----------- not an `extern crate` item
 
 error: attribute should be applied to an `extern crate` item
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:62:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:81:5
    |
 LL |     #[no_link] impl S { }
    |     ^^^^^^^^^^ ---------- not an `extern crate` item
 
 error: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:72:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:17
    |
 LL |     mod inner { #![export_name="2200"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^^^-- not a function or static
 
 error: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:78:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:97:5
    |
 LL |     #[export_name = "2200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static
 
 error: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:82:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:101:5
    |
 LL |     #[export_name = "2200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static
 
 error: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:5
    |
 LL |     #[export_name = "2200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
 
-error: aborting due to 17 previous errors
+error: aborting due to 36 previous errors
 
 For more information about this error, try `rustc --explain E0518`.
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
index f94434f459df9..aba6c08f41dae 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
@@ -1,3 +1,6 @@
+//~ NOTE not a function
+//~^ NOTE not a foreign function or static
+//~^^ NOTE not a function or static
 // This test enumerates as many compiler-builtin ungated attributes as
 // possible (that is, all the mutually compatible ones), and checks
 // that we get "expected" (*) warnings for each in the various weird
@@ -52,20 +55,8 @@
 #![forbid(x5200)] //~ WARN unknown lint: `x5200`
 #![deny(x5100)] //~ WARN unknown lint: `x5100`
 #![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs)
-#![macro_export] //~ WARN unused attribute
 // skipping testing of cfg
 // skipping testing of cfg_attr
-#![main] //~ WARN unused attribute
-#![start] //~ WARN unused attribute
-// see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
-// see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
-#![repr()]
-//~^ WARN unused attribute
-#![path = "3800"] //~ WARN unused attribute
-#![automatically_derived] //~ WARN unused attribute
-#![no_mangle]
-#![no_link] //~ WARN unused attribute
-// see issue-43106-gating-of-derive.rs
 #![should_panic] //~ WARN unused attribute
 #![ignore] //~ WARN unused attribute
 #![no_implicit_prelude]
@@ -75,12 +66,16 @@
 // (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600")
 #![proc_macro_derive()] //~ WARN unused attribute
 #![doc = "2400"]
-#![cold]
-#![export_name = "2200"]
+#![cold] //~ WARN attribute should be applied to a function
+//~^ WARN
 // see issue-43106-gating-of-builtin-attrs-error.rs
 #![link()]
 #![link_name = "1900"]
+//~^ WARN attribute should be applied to a foreign function
+//~^^ WARN this was previously accepted by the compiler
 #![link_section = "1800"]
+//~^ WARN attribute should be applied to a function or static
+//~^^ WARN this was previously accepted by the compiler
 // see issue-43106-gating-of-rustc_deprecated.rs
 #![must_use]
 // see issue-43106-gating-of-stable.rs
@@ -254,42 +249,6 @@ mod plugin_registrar {
     //~| HELP may be removed in a future compiler version
 }
 
-#[main]
-//~^ WARN unused attribute
-mod main {
-    mod inner { #![main] }
-    //~^ WARN unused attribute
-
-    // for `fn f()` case, see feature-gate-main.rs
-
-    #[main] struct S;
-    //~^ WARN unused attribute
-
-    #[main] type T = S;
-    //~^ WARN unused attribute
-
-    #[main] impl S { }
-    //~^ WARN unused attribute
-}
-
-#[start]
-//~^ WARN unused attribute
-mod start {
-    mod inner { #![start] }
-    //~^ WARN unused attribute
-
-    // for `fn f()` case, see feature-gate-start.rs
-
-    #[start] struct S;
-    //~^ WARN unused attribute
-
-    #[start] type T = S;
-    //~^ WARN unused attribute
-
-    #[start] impl S { }
-    //~^ WARN unused attribute
-}
-
 // At time of unit test authorship, if compiling without `--test` then
 // non-crate-level #[test] attributes seem to be ignored.
 
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
index 461c1bd610794..ef9c9ef48a809 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
@@ -1,185 +1,185 @@
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:50:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:9
    |
 LL | #![warn(x5400)]
    |         ^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:37:28
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:28
    |
 LL | #![warn(unused_attributes, unknown_lints)]
    |                            ^^^^^^^^^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:51:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:54:10
    |
 LL | #![allow(x5300)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:52:11
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:11
    |
 LL | #![forbid(x5200)]
    |           ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:53:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:9
    |
 LL | #![deny(x5100)]
    |         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:111:8
    |
 LL | #[warn(x5400)]
    |        ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:25
    |
 LL |     mod inner { #![warn(x5400)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:12
    |
 LL |     #[warn(x5400)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12
    |
 LL |     #[warn(x5400)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:12
    |
 LL |     #[warn(x5400)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:12
    |
 LL |     #[warn(x5400)] impl S { }
    |            ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:130:9
    |
 LL | #[allow(x5300)]
    |         ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:26
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:26
    |
 LL |     mod inner { #![allow(x5300)] }
    |                          ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:13
    |
 LL |     #[allow(x5300)] fn f() { }
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13
    |
 LL |     #[allow(x5300)] struct S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:13
    |
 LL |     #[allow(x5300)] type T = S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:13
    |
 LL |     #[allow(x5300)] impl S { }
    |             ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:149:10
    |
 LL | #[forbid(x5200)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:27
    |
 LL |     mod inner { #![forbid(x5200)] }
    |                           ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:14
    |
 LL |     #[forbid(x5200)] fn f() { }
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14
    |
 LL |     #[forbid(x5200)] struct S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:14
    |
 LL |     #[forbid(x5200)] type T = S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:14
    |
 LL |     #[forbid(x5200)] impl S { }
    |              ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:168:8
    |
 LL | #[deny(x5100)]
    |        ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:25
    |
 LL |     mod inner { #![deny(x5100)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:12
    |
 LL |     #[deny(x5100)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12
    |
 LL |     #[deny(x5100)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:12
    |
 LL |     #[deny(x5100)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:188:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:12
    |
 LL |     #[deny(x5100)] impl S { }
    |            ^^^^^
 
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:1
    |
 LL | #[macro_escape]
    | ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:17
    |
 LL |     mod inner { #![macro_escape] }
    |                 ^^^^^^^^^^^^^^^^
@@ -187,7 +187,7 @@ LL |     mod inner { #![macro_escape] }
    = help: try an outer attribute: `#[macro_use]`
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:233:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
    |
 LL |     mod inner { #![plugin_registrar] }
    |                 ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
@@ -195,49 +195,49 @@ LL |     mod inner { #![plugin_registrar] }
    = note: `#[warn(deprecated)]` on by default
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:236:5
    |
 LL |     #[plugin_registrar] struct S;
    |     ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5
    |
 LL |     #[plugin_registrar] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:251:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5
    |
 LL |     #[plugin_registrar] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1
    |
 LL | #[plugin_registrar]
    | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
 
 warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:43:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1
    |
 LL | #![plugin_registrar]
    | ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
 
 warning: use of deprecated attribute `crate_id`: no longer used.
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:96:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:91:1
    |
 LL | #![crate_id = "10"]
    | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
 
 warning: use of deprecated attribute `no_start`: no longer used.
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:105:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:100:1
    |
 LL | #![no_start]
    | ^^^^^^^^^^^^ help: remove this attribute
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:1
    |
 LL |   #[no_mangle]
    |   ^^^^^^^^^^^^
@@ -252,14 +252,14 @@ LL | | }
    | |_- not a function or static
    |
 note: the lint level is defined here
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:37:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:9
    |
 LL | #![warn(unused_attributes, unknown_lints)]
    |         ^^^^^^^^^^^^^^^^^
    = 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:541:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1
    |
 LL |   #[cold]
    |   ^^^^^^^
@@ -276,7 +276,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:570:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:529:1
    |
 LL |   #[link_name = "1900"]
    |   ^^^^^^^^^^^^^^^^^^^^^
@@ -293,7 +293,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:609:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:568:1
    |
 LL |   #[link_section = "1800"]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -309,8 +309,32 @@ 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
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
+   |
+LL | #![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 foreign function or static
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:73:1
+   |
+LL | #![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 function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1
+   |
+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: attribute should be applied to a function or static
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:17
    |
 LL |     mod inner { #![no_mangle] }
    |     ------------^^^^^^^^^^^^^-- not a function or static
@@ -318,7 +342,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 function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5
    |
 LL |     #[no_mangle] struct S;
    |     ^^^^^^^^^^^^ --------- not a function or static
@@ -326,7 +350,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 function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:391:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5
    |
 LL |     #[no_mangle] type T = S;
    |     ^^^^^^^^^^^^ ----------- not a function or static
@@ -334,7 +358,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 function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:396:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:5
    |
 LL |     #[no_mangle] impl S { }
    |     ^^^^^^^^^^^^ ---------- not a function or static
@@ -342,7 +366,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 function
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:17
    |
 LL |     mod inner { #![cold] }
    |     ------------^^^^^^^^-- not a function
@@ -350,7 +374,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:554:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:5
    |
 LL |     #[cold] struct S;
    |     ^^^^^^^ --------- not a function
@@ -358,7 +382,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:559:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:5
    |
 LL |     #[cold] type T = S;
    |     ^^^^^^^ ----------- not a function
@@ -366,7 +390,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:564:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:5
    |
 LL |     #[cold] impl S { }
    |     ^^^^^^^ ---------- not a function
@@ -374,7 +398,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:576:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -384,13 +408,13 @@ LL |     extern { }
    |
    = 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:576:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:583:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:17
    |
 LL |     mod inner { #![link_name="1900"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^-- not a foreign function or static
@@ -398,7 +422,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:588:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
    |
 LL |     #[link_name = "1900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -406,7 +430,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:593:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:552:5
    |
 LL |     #[link_name = "1900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^ --------- not a foreign function or static
@@ -414,7 +438,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:598:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:557:5
    |
 LL |     #[link_name = "1900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^ ----------- not a foreign function or static
@@ -422,7 +446,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:603:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:562:5
    |
 LL |     #[link_name = "1900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -430,7 +454,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:615:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:574:17
    |
 LL |     mod inner { #![link_section="1800"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^^^^-- not a function or static
@@ -438,7 +462,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:622:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:5
    |
 LL |     #[link_section = "1800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static
@@ -446,7 +470,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:627:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:586:5
    |
 LL |     #[link_section = "1800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static
@@ -454,7 +478,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:632:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:591:5
    |
 LL |     #[link_section = "1800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
@@ -462,7 +486,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: 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:101:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:96:12
    |
 LL | #![feature(rust1)]
    |            ^^^^^
@@ -470,952 +494,850 @@ LL | #![feature(rust1)]
    = note: `#[warn(stable_features)]` on by default
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:196:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5
    |
 LL |     #[macro_use] fn f() { }
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5
    |
 LL |     #[macro_use] struct S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:202:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:5
    |
 LL |     #[macro_use] type T = S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:5
    |
 LL |     #[macro_use] impl S { }
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:17
    |
 LL |     mod inner { #![macro_export] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:215:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:5
    |
 LL |     #[macro_export] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:218:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5
    |
 LL |     #[macro_export] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:5
    |
 LL |     #[macro_export] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:5
    |
 LL |     #[macro_export] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:209:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:1
    |
 LL | #[macro_export]
    | ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:233:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:17
    |
 LL |     mod inner { #![plugin_registrar] }
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:236:5
    |
 LL |     #[plugin_registrar] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:241:5
    |
 LL |     #[plugin_registrar] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:251:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:246:5
    |
 LL |     #[plugin_registrar] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:228:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:223:1
    |
 LL | #[plugin_registrar]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:17
-   |
-LL |     mod inner { #![main] }
-   |                 ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:5
-   |
-LL |     #[main] struct S;
-   |     ^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5
-   |
-LL |     #[main] type T = S;
-   |     ^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5
-   |
-LL |     #[main] impl S { }
-   |     ^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:1
-   |
-LL | #[main]
-   | ^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:278:17
-   |
-LL |     mod inner { #![start] }
-   |                 ^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:283:5
-   |
-LL |     #[start] struct S;
-   |     ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:286:5
-   |
-LL |     #[start] type T = S;
-   |     ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:289:5
-   |
-LL |     #[start] impl S { }
-   |     ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:1
-   |
-LL | #[start]
-   | ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:301:5
    |
 LL |     #[path = "3800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:304:5
    |
 LL |     #[path = "3800"]  struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:307:5
    |
 LL |     #[path = "3800"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:5
    |
 LL |     #[path = "3800"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:317:17
    |
 LL |     mod inner { #![automatically_derived] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5
    |
 LL |     #[automatically_derived] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:323:5
    |
 LL |     #[automatically_derived] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5
    |
 LL |     #[automatically_derived] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:5
    |
 LL |     #[automatically_derived] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:1
    |
 LL | #[automatically_derived]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:17
    |
 LL |     mod inner { #![should_panic] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5
    |
 LL |     #[should_panic] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
    |
 LL |     #[should_panic] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5
    |
 LL |     #[should_panic] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5
    |
 LL |     #[should_panic] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:1
    |
 LL | #[should_panic]
    | ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:17
    |
 LL |     mod inner { #![ignore] }
    |                 ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
    |
 LL |     #[ignore] fn f() { }
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5
    |
 LL |     #[ignore] struct S;
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:5
    |
 LL |     #[ignore] type T = S;
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:5
    |
 LL |     #[ignore] impl S { }
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:1
    |
 LL | #[ignore]
    | ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:443:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:17
    |
 LL |     mod inner { #![no_implicit_prelude] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:446:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:5
    |
 LL |     #[no_implicit_prelude] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:449:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5
    |
 LL |     #[no_implicit_prelude] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:452:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5
    |
 LL |     #[no_implicit_prelude] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5
    |
 LL |     #[no_implicit_prelude] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:440:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:399:1
    |
 LL | #[no_implicit_prelude]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:17
    |
 LL |     mod inner { #![reexport_test_harness_main="2900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:5
    |
 LL |     #[reexport_test_harness_main = "2900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5
    |
 LL |     #[reexport_test_harness_main = "2900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5
    |
 LL |     #[reexport_test_harness_main = "2900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5
    |
 LL |     #[reexport_test_harness_main = "2900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:459:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:1
    |
 LL | #[reexport_test_harness_main = "2900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:5
    |
 LL |     #[macro_escape] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
    |
 LL |     #[macro_escape] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
    |
 LL |     #[macro_escape] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5
    |
 LL |     #[macro_escape] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17
    |
 LL |     mod inner { #![no_std] }
    |                 ^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:462:17
    |
 LL |     mod inner { #![no_std] }
    |                 ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:507:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466: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:507:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
    |
 LL |     #[no_std] fn f() { }
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:511:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470: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:511:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
    |
 LL |     #[no_std] struct S;
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:515:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474: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:515:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5
    |
 LL |     #[no_std] type T = S;
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:5
    |
 LL |     #[no_std] impl S { }
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:5
    |
 LL |     #[no_std] impl S { }
    |     ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
    |
 LL | #[no_std]
    | ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:1
    |
 LL | #[no_std]
    | ^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667: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:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671: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:712:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675: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:716:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 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:679:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659: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:700:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692: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:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696: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:737:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700: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:741:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
    |
 LL |     #[crate_type = "0800"] impl 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:704:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684: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:725:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717: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:758:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721: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:762:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725: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:766:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709: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:750:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17
    |
 LL |     mod inner { #![no_main] }
    |                 ^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17
    |
 LL |     mod inner { #![no_main] }
    |                 ^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743: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:784:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5
    |
 LL |     #[no_main] fn f() { }
    |     ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747: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:788:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:5
    |
 LL |     #[no_main] struct S;
    |     ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751: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:792:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
    |
 LL |     #[no_main] type T = S;
    |     ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
    |
 LL |     #[no_main] impl S { }
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
    |
 LL |     #[no_main] impl S { }
    |     ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735: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:776:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:1
    |
 LL | #[no_main]
    | ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:777:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781: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:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785: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:826:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789: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:830:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773: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:814:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:802:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806: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:847:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810: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:851:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814: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:855:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:859:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:859:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
    |
 LL | #[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:839:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:43:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:46:1
    |
 LL | #![plugin_registrar]
    | ^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
-   |
-LL | #![macro_export]
-   | ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:58:1
-   |
-LL | #![main]
-   | ^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:59:1
-   |
-LL | #![start]
-   | ^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
-   |
-LL | #![repr()]
-   | ^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
-   |
-LL | #![path = "3800"]
-   | ^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
-   |
-LL | #![automatically_derived]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
-   |
-LL | #![no_link]
-   | ^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1
    |
 LL | #![should_panic]
    | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:61:1
    |
 LL | #![ignore]
    | ^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
    |
 LL | #![proc_macro_derive()]
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: 219 warnings emitted
+warning: 205 warnings emitted
 
diff --git a/src/test/ui/traits/issue-75627.rs b/src/test/ui/traits/issue-75627.rs
new file mode 100644
index 0000000000000..93a2ec1cc50c3
--- /dev/null
+++ b/src/test/ui/traits/issue-75627.rs
@@ -0,0 +1,6 @@
+struct Foo<T>(T, *const ());
+
+unsafe impl Send for Foo<T> {}
+//~^ ERROR cannot find type
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-75627.stderr b/src/test/ui/traits/issue-75627.stderr
new file mode 100644
index 0000000000000..92d9ac0f84c99
--- /dev/null
+++ b/src/test/ui/traits/issue-75627.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/issue-75627.rs:3:26
+   |
+LL | unsafe impl Send for Foo<T> {}
+   |                          ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/try-block/try-block-bad-lifetime.rs b/src/test/ui/try-block/try-block-bad-lifetime.rs
index 6063e2e463e2e..d9524e99f9ad0 100644
--- a/src/test/ui/try-block/try-block-bad-lifetime.rs
+++ b/src/test/ui/try-block/try-block-bad-lifetime.rs
@@ -2,7 +2,7 @@
 
 #![feature(try_blocks)]
 
-#![inline(never)]
+#[inline(never)]
 fn do_something_with<T>(_x: T) {}
 
 // This test checks that borrows made and returned inside try blocks are properly constrained
diff --git a/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs b/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs
index 1d1c3d980e230..cd2ddf63a2f01 100644
--- a/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs
+++ b/src/test/ui/try-block/try-block-maybe-bad-lifetime.rs
@@ -2,7 +2,7 @@
 
 #![feature(try_blocks)]
 
-#![inline(never)]
+#[inline(never)]
 fn do_something_with<T>(_x: T) {}
 
 // This test checks that borrows made and returned inside try blocks are properly constrained
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index 4f89c31936dda..4ae4dbfc06ede 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -11,3 +11,6 @@ serde_json = "1.0"
 anyhow = "1.0.32"
 flate2 = "1.0.16"
 tar = "0.4.29"
+sha2 = "0.9.1"
+rayon = "1.3.1"
+hex = "0.4.2"
diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md
index 4d7d9f7da1874..26e96c9fd8fda 100644
--- a/src/tools/build-manifest/README.md
+++ b/src/tools/build-manifest/README.md
@@ -20,8 +20,7 @@ Then, you can generate the manifest and all the packages from `path/to/dist` to
 `path/to/output` with:
 
 ```
-$ BUILD_MANIFEST_DISABLE_SIGNING=1 cargo +nightly run \
-    path/to/dist path/to/output 1970-01-01 http://example.com \
+$ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com \
     CHANNEL path/to/rust/repo
 ```
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index e1dc9111bf326..c7e7d88c68fa8 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -4,17 +4,22 @@
 //! via `x.py dist hash-and-sign`; the cmdline arguments are set up
 //! by rustbuild (in `src/bootstrap/dist.rs`).
 
+mod manifest;
 mod versions;
 
+use crate::manifest::{Component, FileHash, Manifest, Package, Rename, Target};
 use crate::versions::{PkgType, Versions};
-use serde::Serialize;
-use std::collections::BTreeMap;
-use std::collections::HashMap;
+use rayon::prelude::*;
+use sha2::Digest;
+use std::collections::{BTreeMap, HashMap, HashSet};
 use std::env;
+use std::error::Error;
 use std::fs::{self, File};
-use std::io::{self, Read, Write};
+use std::io::{self, BufReader, Read, Write};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
+use std::sync::Mutex;
+use std::time::Instant;
 
 static HOSTS: &[&str] = &[
     "aarch64-unknown-linux-gnu",
@@ -167,57 +172,6 @@ static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"];
 
 static NIGHTLY_ONLY_COMPONENTS: &[&str] = &["miri-preview", "rust-analyzer-preview"];
 
-#[derive(Serialize)]
-#[serde(rename_all = "kebab-case")]
-struct Manifest {
-    manifest_version: String,
-    date: String,
-    pkg: BTreeMap<String, Package>,
-    renames: BTreeMap<String, Rename>,
-    profiles: BTreeMap<String, Vec<String>>,
-}
-
-#[derive(Serialize)]
-struct Package {
-    version: String,
-    git_commit_hash: Option<String>,
-    target: BTreeMap<String, Target>,
-}
-
-#[derive(Serialize)]
-struct Rename {
-    to: String,
-}
-
-#[derive(Serialize, Default)]
-struct Target {
-    available: bool,
-    url: Option<String>,
-    hash: Option<String>,
-    xz_url: Option<String>,
-    xz_hash: Option<String>,
-    components: Option<Vec<Component>>,
-    extensions: Option<Vec<Component>>,
-}
-
-impl Target {
-    fn unavailable() -> Self {
-        Self::default()
-    }
-}
-
-#[derive(Serialize)]
-struct Component {
-    pkg: String,
-    target: String,
-}
-
-impl Component {
-    fn from_str(pkg: &str, target: &str) -> Self {
-        Self { pkg: pkg.to_string(), target: target.to_string() }
-    }
-}
-
 macro_rules! t {
     ($e:expr) => {
         match $e {
@@ -232,25 +186,33 @@ struct Builder {
 
     input: PathBuf,
     output: PathBuf,
-    gpg_passphrase: String,
-    digests: BTreeMap<String, String>,
     s3_address: String,
     date: String,
 
-    should_sign: bool,
+    legacy: bool,
+    legacy_gpg_passphrase: String,
 }
 
 fn main() {
-    // Avoid signing packages while manually testing
-    // Do NOT set this envvar in CI
-    let should_sign = env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err();
-
-    // Safety check to ensure signing is always enabled on CI
-    // The CI environment variable is set by both Travis and AppVeyor
-    if !should_sign && env::var("CI").is_ok() {
-        println!("The 'BUILD_MANIFEST_DISABLE_SIGNING' env var can't be enabled on CI.");
-        println!("If you're not running this on CI, unset the 'CI' env var.");
-        panic!();
+    // Up until Rust 1.48 the release process relied on build-manifest to create the SHA256
+    // checksums of released files and to sign the tarballs. That was moved over to promote-release
+    // in time for the branching of Rust 1.48, but the old release process still had to work the
+    // old way.
+    //
+    // When running build-manifest through the old ./x.py dist hash-and-sign the environment
+    // variable will be set, enabling the legacy behavior of generating the .sha256 files and
+    // signing the tarballs.
+    //
+    // Once the old release process is fully decommissioned, the environment variable, all the
+    // related code in this tool and ./x.py dist hash-and-sign can be removed.
+    let legacy = env::var("BUILD_MANIFEST_LEGACY").is_ok();
+
+    // Avoid overloading the old server in legacy mode.
+    if legacy {
+        rayon::ThreadPoolBuilder::new()
+            .num_threads(1)
+            .build_global()
+            .expect("failed to initialize Rayon");
     }
 
     let mut args = env::args().skip(1);
@@ -263,7 +225,7 @@ fn main() {
 
     // Do not ask for a passphrase while manually testing
     let mut passphrase = String::new();
-    if should_sign {
+    if legacy {
         // `x.py` passes the passphrase via stdin.
         t!(io::stdin().read_to_string(&mut passphrase));
     }
@@ -273,12 +235,11 @@ fn main() {
 
         input,
         output,
-        gpg_passphrase: passphrase,
-        digests: BTreeMap::new(),
         s3_address,
         date,
 
-        should_sign,
+        legacy,
+        legacy_gpg_passphrase: passphrase,
     }
     .build();
 }
@@ -286,7 +247,9 @@ fn main() {
 impl Builder {
     fn build(&mut self) {
         self.check_toolstate();
-        self.digest_and_sign();
+        if self.legacy {
+            self.digest_and_sign();
+        }
         let manifest = self.build_manifest();
 
         let rust_version = self.versions.package_version(&PkgType::Rust).unwrap();
@@ -324,10 +287,9 @@ impl Builder {
     /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
     fn digest_and_sign(&mut self) {
         for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
-            let filename = file.file_name().unwrap().to_str().unwrap();
-            let digest = self.hash(&file);
+            file.file_name().unwrap().to_str().unwrap();
+            self.hash(&file);
             self.sign(&file);
-            assert!(self.digests.insert(filename.to_string(), digest).is_none());
         }
     }
 
@@ -343,6 +305,9 @@ impl Builder {
         self.add_profiles_to(&mut manifest);
         self.add_renames_to(&mut manifest);
         manifest.pkg.insert("rust".to_string(), self.rust_package(&manifest));
+
+        self.fill_missing_hashes(&mut manifest);
+
         manifest
     }
 
@@ -438,9 +403,12 @@ impl Builder {
 
     fn target_host_combination(&mut self, host: &str, manifest: &Manifest) -> Option<Target> {
         let filename = self.versions.tarball_name(&PkgType::Rust, host).unwrap();
-        let digest = self.digests.remove(&filename)?;
-        let xz_filename = filename.replace(".tar.gz", ".tar.xz");
-        let xz_digest = self.digests.remove(&xz_filename);
+
+        let mut target = Target::from_compressed_tar(self, &filename);
+        if !target.available {
+            return None;
+        }
+
         let mut components = Vec::new();
         let mut extensions = Vec::new();
 
@@ -496,15 +464,9 @@ impl Builder {
         extensions.retain(&has_component);
         components.retain(&has_component);
 
-        Some(Target {
-            available: true,
-            url: Some(self.url(&filename)),
-            hash: Some(digest),
-            xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)),
-            xz_hash: xz_digest,
-            components: Some(components),
-            extensions: Some(extensions),
-        })
+        target.components = Some(components);
+        target.extensions = Some(extensions);
+        Some(target)
     }
 
     fn profile(
@@ -542,37 +504,19 @@ impl Builder {
         let targets = targets
             .iter()
             .map(|name| {
-                if is_present {
-                    // The component generally exists, but it might still be missing for this target.
+                let target = if is_present {
                     let filename = self
                         .versions
                         .tarball_name(&PkgType::from_component(pkgname), name)
                         .unwrap();
-                    let digest = match self.digests.remove(&filename) {
-                        Some(digest) => digest,
-                        // This component does not exist for this target -- skip it.
-                        None => return (name.to_string(), Target::unavailable()),
-                    };
-                    let xz_filename = filename.replace(".tar.gz", ".tar.xz");
-                    let xz_digest = self.digests.remove(&xz_filename);
-
-                    (
-                        name.to_string(),
-                        Target {
-                            available: true,
-                            url: Some(self.url(&filename)),
-                            hash: Some(digest),
-                            xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)),
-                            xz_hash: xz_digest,
-                            components: None,
-                            extensions: None,
-                        },
-                    )
+
+                    Target::from_compressed_tar(self, &filename)
                 } else {
                     // If the component is not present for this build add it anyway but mark it as
                     // unavailable -- this way rustup won't allow upgrades without --force
-                    (name.to_string(), Target::unavailable())
-                }
+                    Target::unavailable()
+                };
+                (name.to_string(), target)
             })
             .collect();
 
@@ -586,8 +530,9 @@ impl Builder {
         );
     }
 
-    fn url(&self, filename: &str) -> String {
-        format!("{}/{}/{}", self.s3_address, self.date, filename)
+    fn url(&self, path: &Path) -> String {
+        let file_name = path.file_name().unwrap().to_str().unwrap();
+        format!("{}/{}/{}", self.s3_address, self.date, file_name)
     }
 
     fn hash(&self, path: &Path) -> String {
@@ -608,7 +553,7 @@ impl Builder {
     }
 
     fn sign(&self, path: &Path) {
-        if !self.should_sign {
+        if !self.legacy {
             return;
         }
 
@@ -631,10 +576,45 @@ impl Builder {
             .arg(path)
             .stdin(Stdio::piped());
         let mut child = t!(cmd.spawn());
-        t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes()));
+        t!(child.stdin.take().unwrap().write_all(self.legacy_gpg_passphrase.as_bytes()));
         assert!(t!(child.wait()).success());
     }
 
+    fn fill_missing_hashes(&self, manifest: &mut Manifest) {
+        // First collect all files that need hashes
+        let mut need_hashes = HashSet::new();
+        crate::manifest::visit_file_hashes(manifest, |file_hash| {
+            if let FileHash::Missing(path) = file_hash {
+                need_hashes.insert(path.clone());
+            }
+        });
+
+        let collected = Mutex::new(HashMap::new());
+        let collection_start = Instant::now();
+        println!(
+            "collecting hashes for {} tarballs across {} threads",
+            need_hashes.len(),
+            rayon::current_num_threads().min(need_hashes.len()),
+        );
+        need_hashes.par_iter().for_each(|path| match fetch_hash(path) {
+            Ok(hash) => {
+                collected.lock().unwrap().insert(path, hash);
+            }
+            Err(err) => eprintln!("error while fetching the hash for {}: {}", path.display(), err),
+        });
+        let collected = collected.into_inner().unwrap();
+        println!("collected {} hashes in {:.2?}", collected.len(), collection_start.elapsed());
+
+        crate::manifest::visit_file_hashes(manifest, |file_hash| {
+            if let FileHash::Missing(path) = file_hash {
+                match collected.get(path) {
+                    Some(hash) => *file_hash = FileHash::Present(hash.clone()),
+                    None => panic!("missing hash for file {}", path.display()),
+                }
+            }
+        })
+    }
+
     fn write_channel_files(&self, channel_name: &str, manifest: &Manifest) {
         self.write(&toml::to_string(&manifest).unwrap(), channel_name, ".toml");
         self.write(&manifest.date, channel_name, "-date.txt");
@@ -648,7 +628,16 @@ impl Builder {
     fn write(&self, contents: &str, channel_name: &str, suffix: &str) {
         let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix));
         t!(fs::write(&dst, contents));
-        self.hash(&dst);
-        self.sign(&dst);
+        if self.legacy {
+            self.hash(&dst);
+            self.sign(&dst);
+        }
     }
 }
+
+fn fetch_hash(path: &Path) -> Result<String, Box<dyn Error>> {
+    let mut file = BufReader::new(File::open(path)?);
+    let mut sha256 = sha2::Sha256::default();
+    std::io::copy(&mut file, &mut sha256)?;
+    Ok(hex::encode(sha256.finalize()))
+}
diff --git a/src/tools/build-manifest/src/manifest.rs b/src/tools/build-manifest/src/manifest.rs
new file mode 100644
index 0000000000000..20e62abb54cfa
--- /dev/null
+++ b/src/tools/build-manifest/src/manifest.rs
@@ -0,0 +1,114 @@
+use crate::Builder;
+use serde::{Serialize, Serializer};
+use std::collections::BTreeMap;
+use std::path::{Path, PathBuf};
+
+#[derive(Serialize)]
+#[serde(rename_all = "kebab-case")]
+pub(crate) struct Manifest {
+    pub(crate) manifest_version: String,
+    pub(crate) date: String,
+    pub(crate) pkg: BTreeMap<String, Package>,
+    pub(crate) renames: BTreeMap<String, Rename>,
+    pub(crate) profiles: BTreeMap<String, Vec<String>>,
+}
+
+#[derive(Serialize)]
+pub(crate) struct Package {
+    pub(crate) version: String,
+    pub(crate) git_commit_hash: Option<String>,
+    pub(crate) target: BTreeMap<String, Target>,
+}
+
+#[derive(Serialize)]
+pub(crate) struct Rename {
+    pub(crate) to: String,
+}
+
+#[derive(Serialize, Default)]
+pub(crate) struct Target {
+    pub(crate) available: bool,
+    pub(crate) url: Option<String>,
+    pub(crate) hash: Option<FileHash>,
+    pub(crate) xz_url: Option<String>,
+    pub(crate) xz_hash: Option<FileHash>,
+    pub(crate) components: Option<Vec<Component>>,
+    pub(crate) extensions: Option<Vec<Component>>,
+}
+
+impl Target {
+    pub(crate) fn from_compressed_tar(builder: &Builder, base_path: &str) -> Self {
+        let base_path = builder.input.join(base_path);
+        let gz = Self::tarball_variant(&base_path, "gz");
+        let xz = Self::tarball_variant(&base_path, "xz");
+
+        if gz.is_none() {
+            return Self::unavailable();
+        }
+
+        Self {
+            available: true,
+            components: None,
+            extensions: None,
+            // .gz
+            url: gz.as_ref().map(|path| builder.url(path)),
+            hash: gz.map(FileHash::Missing),
+            // .xz
+            xz_url: xz.as_ref().map(|path| builder.url(path)),
+            xz_hash: xz.map(FileHash::Missing),
+        }
+    }
+
+    fn tarball_variant(base: &Path, ext: &str) -> Option<PathBuf> {
+        let mut path = base.to_path_buf();
+        path.set_extension(ext);
+        if path.is_file() { Some(path) } else { None }
+    }
+
+    pub(crate) fn unavailable() -> Self {
+        Self::default()
+    }
+}
+
+#[derive(Serialize)]
+pub(crate) struct Component {
+    pub(crate) pkg: String,
+    pub(crate) target: String,
+}
+
+impl Component {
+    pub(crate) fn from_str(pkg: &str, target: &str) -> Self {
+        Self { pkg: pkg.to_string(), target: target.to_string() }
+    }
+}
+
+#[allow(unused)]
+pub(crate) enum FileHash {
+    Missing(PathBuf),
+    Present(String),
+}
+
+impl Serialize for FileHash {
+    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+        match self {
+            FileHash::Missing(path) => Err(serde::ser::Error::custom(format!(
+                "can't serialize a missing hash for file {}",
+                path.display()
+            ))),
+            FileHash::Present(inner) => inner.serialize(serializer),
+        }
+    }
+}
+
+pub(crate) fn visit_file_hashes(manifest: &mut Manifest, mut f: impl FnMut(&mut FileHash)) {
+    for pkg in manifest.pkg.values_mut() {
+        for target in pkg.target.values_mut() {
+            if let Some(hash) = &mut target.hash {
+                f(hash);
+            }
+            if let Some(hash) = &mut target.xz_hash {
+                f(hash);
+            }
+        }
+    }
+}