diff --git a/Cargo.lock b/Cargo.lock
index ddacf9cf02463..c105d04c1f440 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -273,7 +273,7 @@ dependencies = [
 
 [[package]]
 name = "cargo"
-version = "0.67.0"
+version = "0.68.0"
 dependencies = [
  "anyhow",
  "atty",
diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
index cb5359dd1e27e..86df3c44eb334 100644
--- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
@@ -34,6 +34,7 @@ impl MultiItemModifier for Expander {
         span: Span,
         meta_item: &ast::MetaItem,
         item: Annotatable,
+        _is_derive_const: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
         let template = AttributeTemplate { list: Some("path"), ..Default::default() };
         let attr = &ecx.attribute(meta_item.clone());
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index e0fb7affb3498..01f237e6ab5fa 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -10,7 +10,7 @@ use rustc_session::Session;
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 
-pub(crate) struct Expander;
+pub(crate) struct Expander(pub bool);
 
 impl MultiItemModifier for Expander {
     fn expand(
@@ -19,6 +19,7 @@ impl MultiItemModifier for Expander {
         span: Span,
         meta_item: &ast::MetaItem,
         item: Annotatable,
+        _: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
         let sess = ecx.sess;
         if report_bad_target(sess, &item, span) {
@@ -58,20 +59,20 @@ impl MultiItemModifier for Expander {
                         report_path_args(sess, &meta);
                         meta.path
                     })
-                    .map(|path| (path, dummy_annotatable(), None))
+                    .map(|path| (path, dummy_annotatable(), None, self.0))
                     .collect();
 
                 // Do not configure or clone items unless necessary.
                 match &mut resolutions[..] {
                     [] => {}
-                    [(_, first_item, _), others @ ..] => {
+                    [(_, first_item, ..), others @ ..] => {
                         *first_item = cfg_eval(
                             sess,
                             features,
                             item.clone(),
                             ecx.current_expansion.lint_node_id,
                         );
-                        for (_, item, _) in others {
+                        for (_, item, _, _) in others {
                             *item = first_item.clone();
                         }
                     }
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 7bd344467d032..345db700298a8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -12,6 +12,7 @@ pub fn expand_deriving_copy(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let trait_def = TraitDef {
         span,
@@ -22,6 +23,7 @@ pub fn expand_deriving_copy(
         supports_unions: true,
         methods: Vec::new(),
         associated_types: Vec::new(),
+        is_const,
     };
 
     trait_def.expand(cx, mitem, item, push);
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index fa8685f5f4e56..55cbb65472328 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -14,6 +14,7 @@ pub fn expand_deriving_clone(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     // The simple form is `fn clone(&self) -> Self { *self }`, possibly with
     // some additional `AssertParamIsClone` assertions.
@@ -87,6 +88,7 @@ pub fn expand_deriving_clone(
             combine_substructure: substructure,
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     trait_def.expand_ext(cx, mitem, item, push, is_simple)
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index eab67b0d354cf..6190b7a8c779e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -15,6 +15,7 @@ pub fn expand_deriving_eq(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let span = cx.with_def_site_ctxt(span);
     let inline = cx.meta_word(span, sym::inline);
@@ -42,6 +43,7 @@ pub fn expand_deriving_eq(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 7f117981a9a2f..d2412b20a09c8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -13,6 +13,7 @@ pub fn expand_deriving_ord(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let inline = cx.meta_word(span, sym::inline);
     let attrs = thin_vec![cx.attribute(inline)];
@@ -34,6 +35,7 @@ pub fn expand_deriving_ord(
             combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 236cbccaf9fee..353f28fc45fb7 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
         let base = true;
@@ -89,6 +90,7 @@ pub fn expand_deriving_partial_eq(
         supports_unions: false,
         methods,
         associated_types: Vec::new(),
+        is_const,
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 4173403a1b84a..e7458b23ef387 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -13,6 +13,7 @@ pub fn expand_deriving_partial_ord(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let ordering_ty = Path(path_std!(cmp::Ordering));
     let ret_ty =
@@ -43,6 +44,7 @@ pub fn expand_deriving_partial_ord(
         supports_unions: false,
         methods: vec![partial_cmp_def],
         associated_types: Vec::new(),
+        is_const,
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index 2cf614ed9476c..e6d5759bb5210 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -13,6 +13,7 @@ pub fn expand_deriving_debug(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     // &mut ::std::fmt::Formatter
     let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut);
@@ -37,6 +38,7 @@ pub fn expand_deriving_debug(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index d669f616802fe..37aa665e5c607 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let krate = sym::rustc_serialize;
     let typaram = sym::__D;
@@ -55,6 +56,7 @@ pub fn expand_deriving_rustc_decodable(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 17df9fb279ad6..234957ab8a16b 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -16,6 +16,7 @@ pub fn expand_deriving_default(
     mitem: &ast::MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
 
@@ -47,6 +48,7 @@ pub fn expand_deriving_default(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
     trait_def.expand(cx, mitem, item, push)
 }
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index f83f58b97d38f..baacaa8b979e1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let krate = sym::rustc_serialize;
     let typaram = sym::__S;
@@ -139,6 +140,7 @@ pub fn expand_deriving_rustc_encodable(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     trait_def.expand(cx, mitem, item, push)
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 16ee3aa89bb12..3972c3b493410 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData};
 use rustc_attr as attr;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use std::cell::RefCell;
 use std::iter;
 use std::ops::Not;
@@ -204,6 +204,8 @@ pub struct TraitDef<'a> {
     pub methods: Vec<MethodDef<'a>>,
 
     pub associated_types: Vec<(Ident, Ty)>,
+
+    pub is_const: bool,
 }
 
 pub struct MethodDef<'a> {
@@ -730,7 +732,7 @@ impl<'a> TraitDef<'a> {
                 unsafety: ast::Unsafe::No,
                 polarity: ast::ImplPolarity::Positive,
                 defaultness: ast::Defaultness::Final,
-                constness: ast::Const::No,
+                constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No },
                 generics: trait_generics,
                 of_trait: opt_trait_ref,
                 self_ty: self_type,
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 6e9d5f08b9443..8fb1a4ba262ab 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -13,6 +13,7 @@ pub fn expand_deriving_hash(
     mitem: &MetaItem,
     item: &Annotatable,
     push: &mut dyn FnMut(Annotatable),
+    is_const: bool,
 ) {
     let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std);
 
@@ -39,6 +40,7 @@ pub fn expand_deriving_hash(
             })),
         }],
         associated_types: Vec::new(),
+        is_const,
     };
 
     hash_trait_def.expand(cx, mitem, item, push);
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index ee346047a0bc0..73a1df5d426d2 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -38,9 +38,10 @@ pub mod partial_ord;
 
 pub mod generic;
 
-pub(crate) struct BuiltinDerive(
-    pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)),
-);
+pub(crate) type BuiltinDeriveFn =
+    fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
+
+pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn);
 
 impl MultiItemModifier for BuiltinDerive {
     fn expand(
@@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive {
         span: Span,
         meta_item: &MetaItem,
         item: Annotatable,
+        is_derive_const: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
         // FIXME: Built-in derives often forget to give spans contexts,
         // so we are doing it here in a centralized way.
@@ -57,21 +59,28 @@ impl MultiItemModifier for BuiltinDerive {
         match item {
             Annotatable::Stmt(stmt) => {
                 if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
-                    (self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| {
-                        // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
-                        // to the function
-                        items.push(Annotatable::Stmt(P(ast::Stmt {
-                            id: ast::DUMMY_NODE_ID,
-                            kind: ast::StmtKind::Item(a.expect_item()),
-                            span,
-                        })));
-                    });
+                    (self.0)(
+                        ecx,
+                        span,
+                        meta_item,
+                        &Annotatable::Item(item),
+                        &mut |a| {
+                            // Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
+                            // to the function
+                            items.push(Annotatable::Stmt(P(ast::Stmt {
+                                id: ast::DUMMY_NODE_ID,
+                                kind: ast::StmtKind::Item(a.expect_item()),
+                                span,
+                            })));
+                        },
+                        is_derive_const,
+                    );
                 } else {
                     unreachable!("should have already errored on non-item statement")
                 }
             }
             _ => {
-                (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
+                (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const);
             }
         }
         ExpandResult::Ready(items)
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index bde0102186a47..1cbbfb432647c 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -99,7 +99,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         bench: test::expand_bench,
         cfg_accessible: cfg_accessible::Expander,
         cfg_eval: cfg_eval::expand,
-        derive: derive::Expander,
+        derive: derive::Expander(false),
+        derive_const: derive::Expander(true),
         global_allocator: global_allocator::expand,
         test: test::expand_test,
         test_case: test::expand_test_case,
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 11053a8f6c452..97d0de47b3a6e 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -765,11 +765,21 @@ pub(crate) unsafe fn codegen(
         drop(handlers);
     }
 
+    // `.dwo` files are only emitted if:
+    //
+    // - Object files are being emitted (i.e. bitcode only or metadata only compilations will not
+    //   produce dwarf objects, even if otherwise enabled)
+    // - Target supports Split DWARF
+    // - Split debuginfo is enabled
+    // - Split DWARF kind is `split` (i.e. debuginfo is split into `.dwo` files, not different
+    //   sections in the `.o` files).
+    let dwarf_object_emitted = matches!(config.emit_obj, EmitObj::ObjectCode(_))
+        && cgcx.target_can_use_split_dwarf
+        && cgcx.split_debuginfo != SplitDebuginfo::Off
+        && cgcx.split_dwarf_kind == SplitDwarfKind::Split;
     Ok(module.into_compiled_module(
         config.emit_obj != EmitObj::None,
-        cgcx.target_can_use_split_dwarf
-            && cgcx.split_debuginfo != SplitDebuginfo::Off
-            && cgcx.split_dwarf_kind == SplitDwarfKind::Split,
+        dwarf_object_emitted,
         config.emit_bc,
         &cgcx.output_filenames,
     ))
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 825011941a241..cf590a43826e5 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -340,17 +340,26 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
 
             sym::black_box => {
                 args[0].val.store(self, result);
-
+                let result_val_span = [result.llval];
                 // We need to "use" the argument in some way LLVM can't introspect, and on
                 // targets that support it we can typically leverage inline assembly to do
                 // this. LLVM's interpretation of inline assembly is that it's, well, a black
                 // box. This isn't the greatest implementation since it probably deoptimizes
                 // more than we want, but it's so far good enough.
+                //
+                // For zero-sized types, the location pointed to by the result may be
+                // uninitialized. Do not "use" the result in this case; instead just clobber
+                // the memory.
+                let (constraint, inputs): (&str, &[_]) = if result.layout.is_zst() {
+                    ("~{memory}", &[])
+                } else {
+                    ("r,~{memory}", &result_val_span)
+                };
                 crate::asm::inline_asm_call(
                     self,
                     "",
-                    "r,~{memory}",
-                    &[result.llval],
+                    constraint,
+                    inputs,
                     self.type_void(),
                     true,
                     false,
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 5a1ad792924fc..cc9367f53265a 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1582,6 +1582,9 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
 /// We only provide such support for a very limited number of targets.
 fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
     if let Some(self_contained) = sess.opts.cg.link_self_contained {
+        if sess.target.link_self_contained == LinkSelfContainedDefault::False {
+            sess.emit_err(errors::UnsupportedLinkSelfContained);
+        }
         return self_contained;
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 752f6b1ef40c9..5930b99f1c8a8 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -224,10 +224,17 @@ fn exported_symbols_provider_local<'tcx>(
         // These are weak symbols that point to the profile version and the
         // profile name, which need to be treated as exported so LTO doesn't nix
         // them.
-        const PROFILER_WEAK_SYMBOLS: [&str; 2] =
-            ["__llvm_profile_raw_version", "__llvm_profile_filename"];
-
-        symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| {
+        // __llvm_profile_counter_bias is not weak, but is only referenced by the
+        // profiling initialization runtime, which is itself pulled in by an
+        // undefined reference to __llvm_profile_runtime. This happens at link time
+        // and thus this symbol cannot be internalized until then.
+        const PROFILER_DEFAULT_VIS_SYMBOLS: [&str; 3] = [
+            "__llvm_profile_raw_version",
+            "__llvm_profile_filename",
+            "__llvm_profile_counter_bias",
+        ];
+
+        symbols.extend(PROFILER_DEFAULT_VIS_SYMBOLS.iter().map(|sym| {
             let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, sym));
             (
                 exported_symbol,
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 36c94462b0b3e..d24579364c476 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -521,3 +521,7 @@ pub enum AppleSdkRootError<'a> {
     #[diag(codegen_ssa_apple_sdk_error_sdk_path)]
     SdkPath { sdk_name: &'a str, error: Error },
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unsupported_link_self_contained)]
+pub struct UnsupportedLinkSelfContained;
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index ad0d758210175..717c7816fabc2 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -182,3 +182,5 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$
 codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
 
 codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}
+
+codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index c8de60ccb89b9..1294f1e17d412 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -250,6 +250,7 @@ pub trait MultiItemModifier {
         span: Span,
         meta_item: &ast::MetaItem,
         item: Annotatable,
+        is_derive_const: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable>;
 }
 
@@ -263,6 +264,7 @@ where
         span: Span,
         meta_item: &ast::MetaItem,
         item: Annotatable,
+        _is_derive_const: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
         ExpandResult::Ready(self(ecx, span, meta_item, item))
     }
@@ -873,7 +875,7 @@ impl SyntaxExtension {
 /// Error type that denotes indeterminacy.
 pub struct Indeterminate;
 
-pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>)>;
+pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>, bool)>;
 
 pub trait ResolverExpand {
     fn next_node_id(&mut self) -> NodeId;
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 57713fb3cd61d..3d37e2c656851 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -337,6 +337,7 @@ pub enum InvocationKind {
     },
     Derive {
         path: ast::Path,
+        is_const: bool,
         item: Annotatable,
     },
 }
@@ -478,13 +479,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                             derive_invocations.reserve(derives.len());
                             derives
                                 .into_iter()
-                                .map(|(path, item, _exts)| {
+                                .map(|(path, item, _exts, is_const)| {
                                     // FIXME: Consider using the derive resolutions (`_exts`)
                                     // instead of enqueuing the derives to be resolved again later.
                                     let expn_id = LocalExpnId::fresh_empty();
                                     derive_invocations.push((
                                         Invocation {
-                                            kind: InvocationKind::Derive { path, item },
+                                            kind: InvocationKind::Derive { path, item, is_const },
                                             fragment_kind,
                                             expansion_data: ExpansionData {
                                                 id: expn_id,
@@ -717,7 +718,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 SyntaxExtensionKind::LegacyAttr(expander) => {
                     match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
                         Ok(meta) => {
-                            let items = match expander.expand(self.cx, span, &meta, item) {
+                            let items = match expander.expand(self.cx, span, &meta, item, false) {
                                 ExpandResult::Ready(items) => items,
                                 ExpandResult::Retry(item) => {
                                     // Reassemble the original invocation for retrying.
@@ -749,19 +750,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 }
                 _ => unreachable!(),
             },
-            InvocationKind::Derive { path, item } => match ext {
+            InvocationKind::Derive { path, item, is_const } => match ext {
                 SyntaxExtensionKind::Derive(expander)
                 | SyntaxExtensionKind::LegacyDerive(expander) => {
                     if let SyntaxExtensionKind::Derive(..) = ext {
                         self.gate_proc_macro_input(&item);
                     }
                     let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path };
-                    let items = match expander.expand(self.cx, span, &meta, item) {
+                    let items = match expander.expand(self.cx, span, &meta, item, is_const) {
                         ExpandResult::Ready(items) => items,
                         ExpandResult::Retry(item) => {
                             // Reassemble the original invocation for retrying.
                             return ExpandResult::Retry(Invocation {
-                                kind: InvocationKind::Derive { path: meta.path, item },
+                                kind: InvocationKind::Derive { path: meta.path, item, is_const },
                                 ..invoc
                             });
                         }
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 1a2ab9d190ebd..e9a6919206894 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -112,6 +112,7 @@ impl MultiItemModifier for DeriveProcMacro {
         span: Span,
         _meta_item: &ast::MetaItem,
         item: Annotatable,
+        _is_derive_const: bool,
     ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
         // We need special handling for statement items
         // (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index e94e038f9283b..a0e16b18061aa 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -512,9 +512,9 @@ declare_features! (
     (active, thread_local, "1.0.0", Some(29594), None),
     /// Allows defining `trait X = A + B;` alias items.
     (active, trait_alias, "1.24.0", Some(41517), None),
-    /// Allows upcasting trait objects via supertraits.
-    /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
-    (incomplete, trait_upcasting, "1.56.0", Some(65991), None),
+    /// Allows dyn upcasting trait objects via supertraits.
+    /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
+    (active, trait_upcasting, "1.56.0", Some(65991), None),
     /// Allows #[repr(transparent)] on unions (RFC 2645).
     (active, transparent_unions, "1.37.0", Some(60405), None),
     /// Allows inconsistent bounds in where clauses.
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 267077cdab4e6..55cca0cd2d7b5 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -69,6 +69,7 @@ use crate::constrained_generic_params as cgp;
 use crate::errors::SubstsOnOverriddenImpl;
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::TyCtxtInferExt;
@@ -80,6 +81,7 @@ use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
+use tracing::instrument;
 
 pub(super) fn check_min_specialization(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) {
     if let Some(node) = parent_specialization_node(tcx, impl_def_id) {
@@ -103,13 +105,11 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId) -> Opti
 }
 
 /// Check that `impl1` is a sound specialization
+#[instrument(level = "debug", skip(tcx))]
 fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node) {
     if let Some((impl1_substs, impl2_substs)) = get_impl_substs(tcx, impl1_def_id, impl2_node) {
         let impl2_def_id = impl2_node.def_id();
-        debug!(
-            "check_always_applicable(\nimpl1_def_id={:?},\nimpl2_def_id={:?},\nimpl2_substs={:?}\n)",
-            impl1_def_id, impl2_def_id, impl2_substs
-        );
+        debug!(?impl2_def_id, ?impl2_substs);
 
         let parent_substs = if impl2_node.is_from_trait() {
             impl2_substs.to_vec()
@@ -118,12 +118,33 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
         };
 
         let span = tcx.def_span(impl1_def_id);
+        check_constness(tcx, impl1_def_id, impl2_node, span);
         check_static_lifetimes(tcx, &parent_substs, span);
         check_duplicate_params(tcx, impl1_substs, &parent_substs, span);
         check_predicates(tcx, impl1_def_id, impl1_substs, impl2_node, impl2_substs, span);
     }
 }
 
+/// Check that the specializing impl `impl1` is at least as const as the base
+/// impl `impl2`
+fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node, span: Span) {
+    if impl2_node.is_from_trait() {
+        // This isn't a specialization
+        return;
+    }
+
+    let impl1_constness = tcx.constness(impl1_def_id.to_def_id());
+    let impl2_constness = tcx.constness(impl2_node.def_id());
+
+    if let hir::Constness::Const = impl2_constness {
+        if let hir::Constness::NotConst = impl1_constness {
+            tcx.sess
+                .struct_span_err(span, "cannot specialize on const impl with non-const impl")
+                .emit();
+        }
+    }
+}
+
 /// Given a specializing impl `impl1`, and the base impl `impl2`, returns two
 /// substitutions `(S1, S2)` that equate their trait references. The returned
 /// types are expressed in terms of the generics of `impl1`.
@@ -278,15 +299,15 @@ fn check_static_lifetimes<'tcx>(
 
 /// Check whether predicates on the specializing impl (`impl1`) are allowed.
 ///
-/// Each predicate `P` must be:
+/// Each predicate `P` must be one of:
 ///
-/// * global (not reference any parameters)
-/// * `T: Tr` predicate where `Tr` is an always-applicable trait
-/// * on the base `impl impl2`
-///     * Currently this check is done using syntactic equality, which is
-///       conservative but generally sufficient.
-/// * a well-formed predicate of a type argument of the trait being implemented,
+/// * Global (not reference any parameters).
+/// * A `T: Tr` predicate where `Tr` is an always-applicable trait.
+/// * Present on the base impl `impl2`.
+///     * This check is done using the `trait_predicates_eq` function below.
+/// * A well-formed predicate of a type argument of the trait being implemented,
 ///   including the `Self`-type.
+#[instrument(level = "debug", skip(tcx))]
 fn check_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl1_def_id: LocalDefId,
@@ -322,10 +343,7 @@ fn check_predicates<'tcx>(
         .map(|obligation| obligation.predicate)
         .collect()
     };
-    debug!(
-        "check_always_applicable(\nimpl1_predicates={:?},\nimpl2_predicates={:?}\n)",
-        impl1_predicates, impl2_predicates,
-    );
+    debug!(?impl1_predicates, ?impl2_predicates);
 
     // Since impls of always applicable traits don't get to assume anything, we
     // can also assume their supertraits apply.
@@ -373,25 +391,83 @@ fn check_predicates<'tcx>(
     );
 
     for (predicate, span) in impl1_predicates {
-        if !impl2_predicates.contains(&predicate) {
+        if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(tcx, predicate, *pred2, span)) {
             check_specialization_on(tcx, predicate, span)
         }
     }
 }
 
+/// Checks if some predicate on the specializing impl (`predicate1`) is the same
+/// as some predicate on the base impl (`predicate2`).
+///
+/// This basically just checks syntactic equivalence, but is a little more
+/// forgiving since we want to equate `T: Tr` with `T: ~const Tr` so this can work:
+///
+/// ```ignore (illustrative)
+/// #[rustc_specialization_trait]
+/// trait Specialize { }
+///
+/// impl<T: Bound> Tr for T { }
+/// impl<T: ~const Bound + Specialize> const Tr for T { }
+/// ```
+///
+/// However, we *don't* want to allow the reverse, i.e., when the bound on the
+/// specializing impl is not as const as the bound on the base impl:
+///
+/// ```ignore (illustrative)
+/// impl<T: ~const Bound> const Tr for T { }
+/// impl<T: Bound + Specialize> const Tr for T { } // should be T: ~const Bound
+/// ```
+///
+/// So we make that check in this function and try to raise a helpful error message.
+fn trait_predicates_eq<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    predicate1: ty::Predicate<'tcx>,
+    predicate2: ty::Predicate<'tcx>,
+    span: Span,
+) -> bool {
+    let pred1_kind = predicate1.kind().skip_binder();
+    let pred2_kind = predicate2.kind().skip_binder();
+    let (trait_pred1, trait_pred2) = match (pred1_kind, pred2_kind) {
+        (ty::PredicateKind::Trait(pred1), ty::PredicateKind::Trait(pred2)) => (pred1, pred2),
+        // Just use plain syntactic equivalence if either of the predicates aren't
+        // trait predicates or have bound vars.
+        _ => return predicate1 == predicate2,
+    };
+
+    let predicates_equal_modulo_constness = {
+        let pred1_unconsted =
+            ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred1 };
+        let pred2_unconsted =
+            ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred2 };
+        pred1_unconsted == pred2_unconsted
+    };
+
+    if !predicates_equal_modulo_constness {
+        return false;
+    }
+
+    // Check that the predicate on the specializing impl is at least as const as
+    // the one on the base.
+    match (trait_pred2.constness, trait_pred1.constness) {
+        (ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
+            tcx.sess.struct_span_err(span, "missing `~const` qualifier for specialization").emit();
+        }
+        _ => {}
+    }
+
+    true
+}
+
+#[instrument(level = "debug", skip(tcx))]
 fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
-    debug!("can_specialize_on(predicate = {:?})", predicate);
     match predicate.kind().skip_binder() {
         // Global predicates are either always true or always false, so we
         // are fine to specialize on.
         _ if predicate.is_global() => (),
         // We allow specializing on explicitly marked traits with no associated
         // items.
-        ty::PredicateKind::Trait(ty::TraitPredicate {
-            trait_ref,
-            constness: ty::BoundConstness::NotConst,
-            polarity: _,
-        }) => {
+        ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => {
             if !matches!(
                 trait_predicate_kind(tcx, predicate),
                 Some(TraitSpecializationKind::Marker)
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 7f78f5fb8a7b2..be618eb664c3f 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -43,7 +43,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
             || self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
             || self.suggest_into(err, expr, expr_ty, expected)
-            || self.suggest_option_to_bool(err, expr, expr_ty, expected);
+            || self.suggest_option_to_bool(err, expr, expr_ty, expected)
+            || self.suggest_floating_point_literal(err, expr, expected);
 
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
         self.note_need_for_fn_pointer(err, expected, expr_ty);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index a14759e254c49..06e6e4350fcbc 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -374,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let annotation_span = ty.span;
                                 err.span_suggestion(
                                     annotation_span.with_hi(annotation_span.lo()),
-                                    format!("alternatively, consider changing the type annotation"),
+                                    "alternatively, consider changing the type annotation",
                                     suggest_annotation,
                                     Applicability::MaybeIncorrect,
                                 );
@@ -1204,6 +1204,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    #[instrument(skip(self, err))]
+    pub(crate) fn suggest_floating_point_literal(
+        &self,
+        err: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        expected_ty: Ty<'tcx>,
+    ) -> bool {
+        if !expected_ty.is_floating_point() {
+            return false;
+        }
+        match expr.kind {
+            ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [start, end], _) => {
+                err.span_suggestion_verbose(
+                    start.span.shrink_to_hi().with_hi(end.span.lo()),
+                    "remove the unnecessary `.` operator for a floating point literal",
+                    '.',
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            ExprKind::Struct(QPath::LangItem(LangItem::RangeFrom, ..), [start], _) => {
+                err.span_suggestion_verbose(
+                    expr.span.with_lo(start.span.hi()),
+                    "remove the unnecessary `.` operator for a floating point literal",
+                    '.',
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            ExprKind::Struct(QPath::LangItem(LangItem::RangeTo, ..), [end], _) => {
+                err.span_suggestion_verbose(
+                    expr.span.until(end.span),
+                    "remove the unnecessary `.` operator and add an integer part for a floating point literal",
+                    "0.",
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            _ => false,
+        }
+    }
+
     fn is_loop(&self, id: hir::HirId) -> bool {
         let node = self.tcx.hir().get(id);
         matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 9526296f95115..8c7972f8eebb9 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -356,7 +356,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
             has_derive_copy: false,
         });
         let parent_scope = self.invocation_parent_scopes[&expn_id];
-        for (i, (path, _, opt_ext)) in entry.resolutions.iter_mut().enumerate() {
+        for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() {
             if opt_ext.is_none() {
                 *opt_ext = Some(
                     match self.resolve_macro_path(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 54a61483a11a3..b48db73618b0b 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -620,6 +620,7 @@ symbols! {
         deref_mut,
         deref_target,
         derive,
+        derive_const,
         derive_default_enum,
         destruct,
         destructuring_assignment,
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs b/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs
new file mode 100644
index 0000000000000..916b6137b650a
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_nto_qnx_710.rs
@@ -0,0 +1,28 @@
+use super::nto_qnx_base;
+use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "aarch64-unknown-unknown".into(),
+        pointer_width: 64,
+        // from: https://llvm.org/docs/LangRef.html#data-layout
+        // e         = little endian
+        // m:e       = ELF mangling: Private symbols get a .L prefix
+        // i8:8:32   = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
+        // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
+        // i64:64    = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
+        // i128:128  = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
+        // n32:64    = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
+        // S128      = 128 bits are the natural alignment of the stack in bits.
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            max_atomic_width: Some(128),
+            pre_link_args: TargetOptions::link_args(
+                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+                &["-Vgcc_ntoaarch64le_cxx"],
+            ),
+            ..nto_qnx_base::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 77d9a0920036a..e809f646860b0 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -74,6 +74,7 @@ mod linux_musl_base;
 mod linux_uclibc_base;
 mod msvc_base;
 mod netbsd_base;
+mod nto_qnx_base;
 mod openbsd_base;
 mod redox_base;
 mod solaris_base;
@@ -1242,6 +1243,9 @@ supported_targets! {
     ("x86_64-unknown-none", x86_64_unknown_none),
 
     ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl),
+
+    ("aarch64-unknown-nto-qnx7.1.0", aarch64_unknown_nto_qnx_710),
+    ("x86_64-pc-nto-qnx7.1.0", x86_64_pc_nto_qnx710),
 }
 
 /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
diff --git a/compiler/rustc_target/src/spec/nto_qnx_base.rs b/compiler/rustc_target/src/spec/nto_qnx_base.rs
new file mode 100644
index 0000000000000..6fb581ef5ce34
--- /dev/null
+++ b/compiler/rustc_target/src/spec/nto_qnx_base.rs
@@ -0,0 +1,19 @@
+use crate::spec::{cvs, RelroLevel, TargetOptions};
+
+pub fn opts() -> TargetOptions {
+    TargetOptions {
+        crt_static_respected: true,
+        dynamic_linking: true,
+        env: "nto71".into(),
+        executables: true,
+        families: cvs!["unix"],
+        has_rpath: true,
+        has_thread_local: false,
+        linker: Some("qcc".into()),
+        os: "nto".into(),
+        position_independent_executables: true,
+        static_position_independent_executables: true,
+        relro_level: RelroLevel::Full,
+        ..Default::default()
+    }
+}
diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs
index 93a956403e50f..6f0bbf0672d44 100644
--- a/compiler/rustc_target/src/spec/wasm32_wasi.rs
+++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs
@@ -72,7 +72,8 @@
 //! best we can with this target. Don't start relying on too much here unless
 //! you know what you're getting in to!
 
-use super::{crt_objects, wasm_base, Cc, LinkerFlavor, Target};
+use super::crt_objects::{self, LinkSelfContainedDefault};
+use super::{wasm_base, Cc, LinkerFlavor, Target};
 
 pub fn target() -> Target {
     let mut options = wasm_base::options();
@@ -83,6 +84,9 @@ pub fn target() -> Target {
     options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
     options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
 
+    // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
+    options.link_self_contained = LinkSelfContainedDefault::True;
+
     // Right now this is a bit of a workaround but we're currently saying that
     // the target by default has a static crt which we're taking as a signal
     // for "use the bundled crt". If that's turned off then the system's crt
diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs
index 528a84a8b37cb..625d3b37c4f26 100644
--- a/compiler/rustc_target/src/spec/wasm_base.rs
+++ b/compiler/rustc_target/src/spec/wasm_base.rs
@@ -1,4 +1,3 @@
-use super::crt_objects::LinkSelfContainedDefault;
 use super::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel};
 
 pub fn options() -> TargetOptions {
@@ -95,9 +94,6 @@ pub fn options() -> TargetOptions {
 
         pre_link_args,
 
-        // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
-        link_self_contained: LinkSelfContainedDefault::True,
-
         // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when
         // PIC code is implemented this has quite a drastic effect if it stays
         // at the default, `pic`. In an effort to keep wasm binaries as minimal
diff --git a/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs
new file mode 100644
index 0000000000000..e9b3acee2e7f1
--- /dev/null
+++ b/compiler/rustc_target/src/spec/x86_64_pc_nto_qnx710.rs
@@ -0,0 +1,21 @@
+use super::nto_qnx_base;
+use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "x86_64-pc-unknown".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+            .into(),
+        arch: "x86_64".into(),
+        options: TargetOptions {
+            cpu: "x86-64".into(),
+            max_atomic_width: Some(64),
+            pre_link_args: TargetOptions::link_args(
+                LinkerFlavor::Gnu(Cc::Yes, Lld::No),
+                &["-Vgcc_ntox86_64_cxx"],
+            ),
+            ..nto_qnx_base::opts()
+        },
+    }
+}
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 2850d84acc327..32bdc26bc51ad 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1464,6 +1464,19 @@ pub(crate) mod builtin {
         /* compiler built-in */
     }
 
+    /// Attribute macro used to apply derive macros for implementing traits
+    /// in a const context.
+    ///
+    /// See [the reference] for more info.
+    ///
+    /// [the reference]: ../../../reference/attributes/derive.html
+    #[unstable(feature = "derive_const", issue = "none")]
+    #[rustc_builtin_macro]
+    #[cfg(not(bootstrap))]
+    pub macro derive_const($item:item) {
+        /* compiler built-in */
+    }
+
     /// Attribute macro applied to a function to turn it into a unit test.
     ///
     /// See [the reference] for more info.
diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs
index 804a179bdb3c0..d3d255a802d7f 100644
--- a/library/core/src/prelude/v1.rs
+++ b/library/core/src/prelude/v1.rs
@@ -81,6 +81,10 @@ pub use crate::macros::builtin::alloc_error_handler;
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
 
+#[unstable(feature = "derive_const", issue = "none")]
+#[cfg(not(bootstrap))]
+pub use crate::macros::builtin::derive_const;
+
 #[unstable(
     feature = "cfg_accessible",
     issue = "64797",
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 36d9e8921ef31..d5ac16e6b94e2 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -65,6 +65,10 @@ pub use core::prelude::v1::alloc_error_handler;
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
 
+#[unstable(feature = "derive_const", issue = "none")]
+#[cfg(not(bootstrap))]
+pub use core::prelude::v1::derive_const;
+
 // Do not `doc(no_inline)` either.
 #[unstable(
     feature = "cfg_accessible",
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 86bb2c0d3816a..2d3b830946145 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -33,6 +33,7 @@
     - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
     - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
     - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
+    - [\*-nto-qnx-\*](platform-support/nto-qnx.md)
     - [*-unknown-openbsd](platform-support/openbsd.md)
     - [\*-unknown-uefi](platform-support/unknown-uefi.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index f5a49410ea555..7e355b7fccfc4 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -210,8 +210,8 @@ metrics.
 
 ## link-self-contained
 
-On targets that support it this flag controls whether the linker will use libraries and objects
-shipped with Rust instead or those in the system.
+On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the
+linker will use libraries and objects shipped with Rust instead or those in the system.
 It takes one of the following values:
 
 * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 0315f1e3725ff..28929acb9b48d 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -214,6 +214,7 @@ target | std | host | notes
 [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ |  | ARM64 SOLID with TOPPERS/ASP3
 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
+[`aarch64-unknown-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? |  | ARM64 QNX Neutrino 7.1 RTOS |
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
 `aarch64-unknown-hermit` | ✓ |  | ARM64 HermitCore
 `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
@@ -303,6 +304,7 @@ target | std | host | notes
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 `x86_64-apple-tvos` | * | | x86 64-bit tvOS
 [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
+[`x86_64-pc-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? |  | x86 64-bit QNX Neutrino 7.1 RTOS |
 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 `x86_64-pc-windows-msvc` | * |  | 64-bit Windows XP support
 `x86_64-sun-solaris` | ? |  | Deprecated target for 64-bit Solaris 10/11, illumos
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
new file mode 100644
index 0000000000000..62d426bf3161b
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -0,0 +1,118 @@
+# nto-qnx
+
+**Tier: 3**
+
+[BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system.
+The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit]
+and [BlackBerry][BlackBerry].
+
+[BlackBerry]: https://blackberry.qnx.com
+[Elektrobit]: https://www.elektrobit.com
+
+## Target maintainers
+
+- Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb
+- Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr
+
+## Requirements
+
+Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian).
+Adding other architectures that are supported by QNX Neutrino is possible.
+
+The standard library does not yet support QNX Neutrino. Therefore, only `no_std` code can
+be compiled.
+
+`core` and `alloc` (with default allocator) are supported.
+
+Applications must link against `libc.so` (see example). This is required because applications
+always link against the `crt` library and `crt` depends on `libc.so`.
+
+The correct version of `qcc` must be available by setting the `$PATH` variable (e.g. by sourcing `qnxsdp-env.sh` of the
+QNX Neutrino toolchain).
+
+### Small example application
+
+```rust
+#![no_std]
+#![no_main]
+#![feature(lang_items)]
+
+// We must always link against libc, even if no external functions are used
+// "extern C" - Block can be empty but must be present
+#[link(name = "c")]
+extern "C" {
+    pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int;
+}
+
+#[no_mangle]
+pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
+    const HELLO: &'static str = "Hello World, the answer is %d\n\0";
+    unsafe {
+        printf(HELLO.as_ptr() as *const _, 42);
+    }
+    0
+}
+
+use core::panic::PanicInfo;
+
+#[panic_handler]
+fn panic(_panic: &PanicInfo<'_>) -> ! {
+    loop {}
+}
+
+#[lang = "eh_personality"]
+#[no_mangle]
+pub extern "C" fn rust_eh_personality() {}
+```
+
+The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1.
+
+There are no further known requirements.
+
+## Conditional compilation
+
+For conditional compilation, following QNX Neutrino specific attributes are defined:
+
+- `target_os` = `"nto"`
+- `target_env` = `"nto71"` (for QNX Neutrino 7.1)
+
+## Building the target
+
+1. Create a `config.toml`
+
+Example content:
+
+```toml
+profile = "compiler"
+changelog-seen = 2
+```
+
+2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets)
+
+Run the following:
+
+```bash
+env \
+    CC_aarch64-unknown-nto-qnx7.1.0="qcc" \
+    CFLAGS_aarch64-unknown-nto-qnx7.1.0="-Vgcc_ntoaarch64le_cxx" \
+    CXX_aarch64-unknown-nto-qnx7.1.0="qcc" \
+    AR_aarch64_unknown_nto_qnx7.1.0="ntoaarch64-ar" \
+    CC_x86_64-pc-nto-qnx7.1.0="qcc" \
+    CFLAGS_x86_64-pc-nto-qnx7.1.0="-Vgcc_ntox86_64_cxx" \
+    CXX_x86_64-pc-nto-qnx7.1.0="qcc" \
+    AR_x86_64_pc_nto_qnx7.1.0="ntox86_64-ar" \
+        ./x.py build --target aarch64-unknown-nto-qnx7.1.0 --target x86_64-pc-nto-qnx7.1.0 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of  `core` by using
+`build-std` or similar.
+
+## Testing
+
+Compiled executables can directly be run on QNX Neutrino.
+
+## Cross-compilation toolchains and C code
+
+Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout.
diff --git a/src/test/codegen/pgo-counter-bias.rs b/src/test/codegen/pgo-counter-bias.rs
new file mode 100644
index 0000000000000..b9019e9de7b22
--- /dev/null
+++ b/src/test/codegen/pgo-counter-bias.rs
@@ -0,0 +1,9 @@
+// Test that __llvm_profile_counter_bias does not get internalized by lto.
+
+// compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat
+// needs-profiler-support
+// no-prefer-dynamic
+
+// CHECK: @__llvm_profile_counter_bias = {{.*}}global
+
+pub fn main() {}
diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile
index 1032f3408f062..1831ab38fab49 100644
--- a/src/test/run-make-fulldeps/split-debuginfo/Makefile
+++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile
@@ -3,7 +3,7 @@ include ../tools.mk
 all: off packed unpacked
 
 ifeq ($(UNAME),Darwin)
-# If disabled, don't run dsymutil
+# If disabled, don't run `dsymutil`.
 off:
 	rm -rf $(TMPDIR)/*.dSYM
 	$(RUSTC) foo.rs -g -C split-debuginfo=off
@@ -29,98 +29,280 @@ unpacked:
 	[ ! -d $(TMPDIR)/foo.dSYM ]
 else
 ifdef IS_WINDOWS
-# Windows only supports =packed
+# Windows only supports packed debuginfo - nothing to test.
 off:
 packed:
 unpacked:
 else
+# Some non-Windows, non-Darwin platforms are not stable, and some are.
 ifeq ($(UNAME),Linux)
   UNSTABLEOPTS :=
 else
   UNSTABLEOPTS := -Zunstable-options
 endif
 
+# - Debuginfo in `.o` files
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` never created
 off:
 	$(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off
 	[ ! -f $(TMPDIR)/*.dwp ]
 	[ ! -f $(TMPDIR)/*.dwo ]
-
 	$(RUSTC) foo.rs -g
 	[ ! -f $(TMPDIR)/*.dwp ]
 	[ ! -f $(TMPDIR)/*.dwo ]
 
-packed: packed-split packed-single
+packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate
 
+# - Debuginfo in `.dwo` files
+# - `.o` deleted
+# - `.dwo` deleted
+# - `.dwp` present
 packed-split:
 	$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split
-	ls $(TMPDIR)/*.dwp
-	rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	rm $(TMPDIR)/foo.dwp
+	rm $(TMPDIR)/$(call BIN,foo)
 
+# - Debuginfo in `.o` files
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` present
 packed-single:
 	$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single
-	ls $(TMPDIR)/*.dwp
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	rm $(TMPDIR)/foo.dwp
+	rm $(TMPDIR)/$(call BIN,foo)
+
+packed-lto: packed-lto-split packed-lto-single
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+packed-lto-split:
+	$(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split \
+		--crate-type=rlib -Clinker-plugin-lto
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/libbaz.rlib
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+packed-lto-single:
+	$(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single \
+		--crate-type=rlib -Clinker-plugin-lto
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
-	rm -rf $(TMPDIR)/*.dwp
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/libbaz.rlib
 
 packed-remapped: packed-remapped-split packed-remapped-single
 
+# - Debuginfo in `.dwo` files
+# - `.o` and binary refer to remapped `.dwo` paths which do not exist
+# - `.o` deleted
+# - `.dwo` deleted
+# - `.dwp` present
 packed-remapped-split:
 	$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
 		-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
 	objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	rm $(TMPDIR)/foo.dwp
+	rm $(TMPDIR)/$(call BIN,foo)
 
+# - Debuginfo in `.o` files
+# - `.o` and binary refer to remapped `.o` paths which do not exist
+# - `.o` deleted
+# - `.dwo` never created
+# - `.dwp` present
 packed-remapped-single:
 	$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \
 		-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
 	objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	rm $(TMPDIR)/foo.dwp
+	rm $(TMPDIR)/$(call BIN,foo)
 
 packed-crosscrate: packed-crosscrate-split packed-crosscrate-single
 
+# - Debuginfo in `.dwo` files
+# - (bar) `.rlib` file created, contains `.dwo`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` deleted
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` deleted
+# - (main) `.dwp` present
 packed-crosscrate-split:
 	$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
 		-Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs
 	ls $(TMPDIR)/*.rlib
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
-	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
 		-C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
-	rm $(TMPDIR)/*.dwo
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
 	rm $(TMPDIR)/main.dwp
 	rm $(TMPDIR)/$(call BIN,main)
 
+# - Debuginfo in `.o` files
+# - (bar) `.rlib` file created, contains `.o`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` never created
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` never created
+# - (main) `.dwp` present
 packed-crosscrate-single:
 	$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \
 		-Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs
 	ls $(TMPDIR)/*.rlib
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
-	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \
+	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
 		-C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
 	rm $(TMPDIR)/main.dwp
 	rm $(TMPDIR)/$(call BIN,main)
 
-unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single
+unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate
 
+# - Debuginfo in `.dwo` files
+# - `.o` deleted
+# - `.dwo` present
+# - `.dwp` never created
 unpacked-split:
 	$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	rm $(TMPDIR)/*.dwo
 	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
-	ls $(TMPDIR)/*.dwo
-	rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo
+	rm $(TMPDIR)/$(call BIN,foo)
 
+# - Debuginfo in `.o` files
+# - `.o` present
+# - `.dwo` never created
+# - `.dwp` never created
 unpacked-single:
 	$(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single
+	ls $(TMPDIR)/*.o
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/$(call BIN,foo)
+
+unpacked-lto: packed-lto-split packed-lto-single
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+unpacked-lto-split:
+	$(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split \
+		--crate-type=rlib -Clinker-plugin-lto
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/libbaz.rlib
+
+# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated
+# - `.o` never created
+# - `.dwo` never created
+# - `.dwp` never created
+unpacked-lto-single:
+	$(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single \
+		--crate-type=rlib -Clinker-plugin-lto
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
 	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/libbaz.rlib
+
+unpacked-remapped: unpacked-remapped-split unpacked-remapped-single
 
+# - Debuginfo in `.dwo` files
+# - `.o` and binary refer to remapped `.dwo` paths which do not exist
+# - `.o` deleted
+# - `.dwo` present
+# - `.dwp` never created
 unpacked-remapped-split:
 	$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
 		-Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g
 	objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	rm $(TMPDIR)/*.dwo
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/$(call BIN,foo)
 
+# - Debuginfo in `.o` files
+# - `.o` and binary refer to remapped `.o` paths which do not exist
+# - `.o` present
+# - `.dwo` never created
+# - `.dwp` never created
 unpacked-remapped-single:
 	$(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \
 		-Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g
 	objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1
+	ls $(TMPDIR)/*.o
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/$(call BIN,foo)
+
+unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single
+
+# - Debuginfo in `.dwo` files
+# - (bar) `.rlib` file created, contains `.dwo`
+# - (bar) `.o` deleted
+# - (bar) `.dwo` present
+# - (bar) `.dwp` never created
+# - (main) `.o` deleted
+# - (main) `.dwo` present
+# - (main) `.dwp` never created
+unpacked-crosscrate-split:
+	$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \
+		-Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs
+	ls $(TMPDIR)/*.rlib
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwo
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
+		-C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs
+	ls $(TMPDIR)/*.o && exit 1 || exit 0
+	rm $(TMPDIR)/*.dwo
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/$(call BIN,main)
+
+# - Debuginfo in `.o` files
+# - (bar) `.rlib` file created, contains `.o`
+# - (bar) `.o` present
+# - (bar) `.dwo` never created
+# - (bar) `.dwp` never created
+# - (main) `.o` present
+# - (main) `.dwo` never created
+# - (main) `.dwp` never created
+unpacked-crosscrate-single:
+	$(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \
+		-Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs
+	ls $(TMPDIR)/*.rlib
+	ls $(TMPDIR)/*.o
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	$(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \
+		-C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs
+	ls $(TMPDIR)/*.o
+	ls $(TMPDIR)/*.dwo && exit 1 || exit 0
+	ls $(TMPDIR)/*.dwp && exit 1 || exit 0
+	rm $(TMPDIR)/$(call BIN,main)
 endif
 endif
diff --git a/src/test/run-make-fulldeps/split-debuginfo/baz.rs b/src/test/run-make-fulldeps/split-debuginfo/baz.rs
new file mode 100644
index 0000000000000..8b1a393741c96
--- /dev/null
+++ b/src/test/run-make-fulldeps/split-debuginfo/baz.rs
@@ -0,0 +1 @@
+// empty
diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr
index 4ec74494fe09b..6c0dc05ba2330 100644
--- a/src/test/ui/check-cfg/well-known-values.stderr
+++ b/src/test/ui/check-cfg/well-known-values.stderr
@@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")]
    |                   |
    |                   help: did you mean: `"linux"`
    |
-   = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
+   = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous
    = note: `#[warn(unexpected_cfgs)]` on by default
 
 warning: unexpected `cfg` condition value
diff --git a/src/test/ui/codegen/issue-99551.rs b/src/test/ui/codegen/issue-99551.rs
index f24874c992eaf..b223aff4e9492 100644
--- a/src/test/ui/codegen/issue-99551.rs
+++ b/src/test/ui/codegen/issue-99551.rs
@@ -1,6 +1,5 @@
 // build-pass
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 pub trait A {}
 pub trait B {}
diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr
index 2d9ce430a462d..5a758c7002b92 100644
--- a/src/test/ui/issues/issue-32655.stderr
+++ b/src/test/ui/issues/issue-32655.stderr
@@ -2,18 +2,28 @@ error: cannot find attribute `derive_Clone` in this scope
   --> $DIR/issue-32655.rs:3:11
    |
 LL |         #[derive_Clone]
-   |           ^^^^^^^^^^^^
+   |           ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
 ...
 LL | foo!();
    | ------ in this macro invocation
    |
+  ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+   |
+LL |     pub macro derive_const($item:item) {
+   |     ---------------------- similarly named attribute macro `derive_const` defined here
+   |
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: cannot find attribute `derive_Clone` in this scope
   --> $DIR/issue-32655.rs:15:7
    |
 LL |     #[derive_Clone]
-   |       ^^^^^^^^^^^^
+   |       ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
+   |
+  ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
+   |
+LL |     pub macro derive_const($item:item) {
+   |     ---------------------- similarly named attribute macro `derive_const` defined here
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
new file mode 100644
index 0000000000000..348ca0ab1906b
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs
@@ -0,0 +1,4 @@
+#[derive_const(Default)] //~ ERROR use of unstable library feature
+pub struct S;
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
new file mode 100644
index 0000000000000..cc9bdd2715f70
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr
@@ -0,0 +1,11 @@
+error[E0658]: use of unstable library feature 'derive_const'
+  --> $DIR/derive-const-gate.rs:1:3
+   |
+LL | #[derive_const(Default)]
+   |   ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(derive_const)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
new file mode 100644
index 0000000000000..92843a8a2da48
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs
@@ -0,0 +1,13 @@
+#![feature(derive_const)]
+
+pub struct A;
+
+impl Default for A {
+    fn default() -> A { A }
+}
+
+#[derive_const(Default)]
+pub struct S(A);
+//~^ cannot call non-const fn
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr
new file mode 100644
index 0000000000000..d463c774e289e
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr
@@ -0,0 +1,14 @@
+error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions
+  --> $DIR/derive-const-non-const-type.rs:10:14
+   |
+LL | #[derive_const(Default)]
+   |                ------- in this derive macro expansion
+LL | pub struct S(A);
+   |              ^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs
new file mode 100644
index 0000000000000..d1fbeac8598e4
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
+
+pub struct A;
+
+impl const Default for A {
+    fn default() -> A { A }
+}
+
+impl const PartialEq for A {
+    fn eq(&self, _: &A) -> bool { true }
+}
+
+#[derive_const(Default, PartialEq)]
+pub struct S((), A);
+
+const _: () = assert!(S((), A) == S::default());
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
new file mode 100644
index 0000000000000..3ac909924864d
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs
@@ -0,0 +1,46 @@
+// Tests that trait bounds on specializing trait impls must be `~const` if the
+// same bound is present on the default impl and is `~const` there.
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {}
+
+// bgr360: I was only able to exercise the code path that raises the
+// "missing ~const qualifier" error by making this base impl non-const, even
+// though that doesn't really make sense to do. As seen below, if the base impl
+// is made const, rustc fails earlier with an overlapping impl failure.
+impl<T> Bar for T
+where
+    T: ~const Foo,
+{}
+
+impl<T> Bar for T
+where
+    T: Foo, //~ ERROR missing `~const` qualifier
+    T: Specialize,
+{}
+
+#[const_trait]
+trait Baz {}
+
+impl<T> const Baz for T
+where
+    T: ~const Foo,
+{}
+
+impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
+where
+    T: Foo,
+    T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
new file mode 100644
index 0000000000000..4aea1979421c3
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr
@@ -0,0 +1,18 @@
+error: missing `~const` qualifier for specialization
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:8
+   |
+LL |     T: Foo,
+   |        ^^^
+
+error[E0119]: conflicting implementations of trait `Baz`
+  --> $DIR/const-default-bound-non-const-specialized-bound.rs:40:1
+   |
+LL | impl<T> const Baz for T
+   | ----------------------- first implementation here
+...
+LL | impl<T> const Baz for T
+   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
new file mode 100644
index 0000000000000..9ddea427cfd80
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs
@@ -0,0 +1,39 @@
+// Tests that a const default trait impl can be specialized by another const
+// trait impl and that the specializing impl will be used during const-eval.
+
+// run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+    T::value()
+}
+
+impl<T> const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+const ZERO: u32 = get_value::<()>();
+
+const FORTY_TWO: u32 = get_value::<FortyTwo>();
+
+fn main() {
+    assert_eq!(ZERO, 0);
+    assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
new file mode 100644
index 0000000000000..a3bb9b3f93eda
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs
@@ -0,0 +1,26 @@
+// Tests that specializing trait impls must be at least as const as the default impl.
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+impl<T> const Value for T {
+    default fn value() -> u32 {
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl
+    fn value() -> u32 {
+        println!("You can't do that (constly)");
+        42
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
new file mode 100644
index 0000000000000..24766804708a3
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr
@@ -0,0 +1,8 @@
+error: cannot specialize on const impl with non-const impl
+  --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
+   |
+LL | impl Value for FortyTwo {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
new file mode 100644
index 0000000000000..2aac0a2b4d111
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/default-keyword.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Foo {
+    fn foo();
+}
+
+impl const Foo for u32 {
+    default fn foo() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
new file mode 100644
index 0000000000000..9c2c2cf1610a2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs
@@ -0,0 +1,37 @@
+// Tests that `~const` trait bounds can be used to specialize const trait impls.
+
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+
+#[const_trait]
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+impl<T> const Foo for T {}
+
+impl<T> const Foo for T
+where
+    T: ~const Specialize,
+{}
+
+#[const_trait]
+trait Bar {}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+{}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+    T: ~const Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
new file mode 100644
index 0000000000000..1e6b1c6513b39
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs
@@ -0,0 +1,45 @@
+// Tests that `T: ~const Foo` in a specializing impl is treated as equivalent to
+// `T: Foo` in the default impl for the purposes of specialization (i.e., it
+// does not think that the user is attempting to specialize on trait `Foo`).
+
+// check-pass
+
+#![feature(rustc_attrs)]
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+#[rustc_specialization_trait]
+trait Specialize {}
+
+#[const_trait]
+trait Foo {}
+
+#[const_trait]
+trait Bar {}
+
+impl<T> Bar for T
+where
+    T: Foo,
+{}
+
+impl<T> const Bar for T
+where
+    T: ~const Foo,
+    T: Specialize,
+{}
+
+#[const_trait]
+trait Baz {}
+
+impl<T> const Baz for T
+where
+    T: Foo,
+{}
+
+impl<T> const Baz for T
+where
+    T: ~const Foo,
+    T: Specialize,
+{}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
new file mode 100644
index 0000000000000..35aa52fbd4ed2
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs
@@ -0,0 +1,39 @@
+// Tests that a non-const default impl can be specialized by a const trait impl,
+// but that the default impl cannot be used in a const context.
+
+// run-pass
+
+#![feature(const_trait_impl)]
+#![feature(min_specialization)]
+
+#[const_trait]
+trait Value {
+    fn value() -> u32;
+}
+
+const fn get_value<T: ~const Value>() -> u32 {
+    T::value()
+}
+
+impl<T> Value for T {
+    default fn value() -> u32 {
+        println!("You can't do that (constly)");
+        0
+    }
+}
+
+struct FortyTwo;
+
+impl const Value for FortyTwo {
+    fn value() -> u32 {
+        42
+    }
+}
+
+fn main() {
+    let zero = get_value::<()>();
+    assert_eq!(zero, 0);
+
+    const FORTY_TWO: u32 = get_value::<FortyTwo>();
+    assert_eq!(FORTY_TWO, 42);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
index ff0cd489d4744..9ab170f092006 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.rs
@@ -17,7 +17,9 @@ impl<T: ~const Default> const A for T {
     }
 }
 
-impl<T: Default + Sup> A for T { //~ ERROR: cannot specialize
+impl<T: Default + Sup> A for T {
+//~^ ERROR: cannot specialize
+//~| ERROR: missing `~const` qualifier
     fn a() -> u32 {
         3
     }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
index 3296c109c4e73..843fc6ce84d45 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/specializing-constness.stderr
@@ -1,8 +1,14 @@
-error: cannot specialize on trait `Default`
+error: cannot specialize on const impl with non-const impl
+  --> $DIR/specializing-constness.rs:20:1
+   |
+LL | impl<T: Default + Sup> A for T {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing `~const` qualifier for specialization
   --> $DIR/specializing-constness.rs:20:9
    |
 LL | impl<T: Default + Sup> A for T {
    |         ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/sanitize/memory-passing.rs b/src/test/ui/sanitize/memory-passing.rs
new file mode 100644
index 0000000000000..6d9b70ad6b1c2
--- /dev/null
+++ b/src/test/ui/sanitize/memory-passing.rs
@@ -0,0 +1,32 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-pass
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![allow(invalid_value)]
+
+use std::hint::black_box;
+
+fn calling_black_box_on_zst_ok() {
+    // It's OK to call black_box on a value of a zero-sized type, even if its
+    // underlying the memory location is uninitialized. For non-zero-sized types,
+    // this would be an MSAN error.
+    let zst = ();
+    black_box(zst);
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+    calling_black_box_on_zst_ok();
+    0
+}
diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs
new file mode 100644
index 0000000000000..c1a944562683a
--- /dev/null
+++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let _: f64 = 0..10; //~ ERROR mismatched types
+    let _: f64 = 1..; //~ ERROR mismatched types
+    let _: f64 = ..10; //~ ERROR mismatched types
+    let _: f64 = std::ops::Range { start: 0, end: 1 }; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
new file mode 100644
index 0000000000000..773f1392ae765
--- /dev/null
+++ b/src/test/ui/suggestions/unnecessary_dot_for_floating_point_literal.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+  --> $DIR/unnecessary_dot_for_floating_point_literal.rs:2:18
+   |
+LL |     let _: f64 = 0..10;
+   |            ---   ^^^^^ expected `f64`, found struct `std::ops::Range`
+   |            |
+   |            expected due to this
+   |
+   = note: expected type `f64`
+            found struct `std::ops::Range<{integer}>`
+help: remove the unnecessary `.` operator for a floating point literal
+   |
+LL |     let _: f64 = 0.10;
+   |                   ~
+
+error[E0308]: mismatched types
+  --> $DIR/unnecessary_dot_for_floating_point_literal.rs:3:18
+   |
+LL |     let _: f64 = 1..;
+   |            ---   ^^^ expected `f64`, found struct `RangeFrom`
+   |            |
+   |            expected due to this
+   |
+   = note: expected type `f64`
+            found struct `RangeFrom<{integer}>`
+help: remove the unnecessary `.` operator for a floating point literal
+   |
+LL |     let _: f64 = 1.;
+   |                   ~
+
+error[E0308]: mismatched types
+  --> $DIR/unnecessary_dot_for_floating_point_literal.rs:4:18
+   |
+LL |     let _: f64 = ..10;
+   |            ---   ^^^^ expected `f64`, found struct `RangeTo`
+   |            |
+   |            expected due to this
+   |
+   = note: expected type `f64`
+            found struct `RangeTo<{integer}>`
+help: remove the unnecessary `.` operator and add an integer part for a floating point literal
+   |
+LL |     let _: f64 = 0.10;
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/unnecessary_dot_for_floating_point_literal.rs:5:18
+   |
+LL |     let _: f64 = std::ops::Range { start: 0, end: 1 };
+   |            ---   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `f64`, found struct `std::ops::Range`
+   |            |
+   |            expected due to this
+   |
+   = note: expected type `f64`
+            found struct `std::ops::Range<{integer}>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/traits/trait-upcasting/basic.rs b/src/test/ui/traits/trait-upcasting/basic.rs
index 484a222bc012d..570ec5160bfe9 100644
--- a/src/test/ui/traits/trait-upcasting/basic.rs
+++ b/src/test/ui/traits/trait-upcasting/basic.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
     fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
index 8d0a9ef0ace69..eae5cf8d58d01 100644
--- a/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
+++ b/src/test/ui/traits/trait-upcasting/correct-supertrait-substitution.rs
@@ -1,6 +1,5 @@
 // run-pass
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo<T: Default + ToString>: Bar<i32> + Bar<T> {}
 trait Bar<T: Default + ToString> {
diff --git a/src/test/ui/traits/trait-upcasting/diamond.rs b/src/test/ui/traits/trait-upcasting/diamond.rs
index e4e23c1a26e78..a4f81c464b402 100644
--- a/src/test/ui/traits/trait-upcasting/diamond.rs
+++ b/src/test/ui/traits/trait-upcasting/diamond.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
     fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
index 24022450406a7..e634bbd5ac6f5 100644
--- a/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
+++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo {
     fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
index b4530ed0c3a94..3aa21ee3dddfb 100644
--- a/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
+++ b/src/test/ui/traits/trait-upcasting/invalid-upcast.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:54:35
+  --> $DIR/invalid-upcast.rs:53:35
    |
 LL |     let _: &dyn std::fmt::Debug = baz;
    |            --------------------   ^^^ expected trait `Debug`, found trait `Baz`
@@ -10,7 +10,7 @@ LL |     let _: &dyn std::fmt::Debug = baz;
               found reference `&dyn Baz`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:56:24
+  --> $DIR/invalid-upcast.rs:55:24
    |
 LL |     let _: &dyn Send = baz;
    |            ---------   ^^^ expected trait `Send`, found trait `Baz`
@@ -21,7 +21,7 @@ LL |     let _: &dyn Send = baz;
               found reference `&dyn Baz`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:58:24
+  --> $DIR/invalid-upcast.rs:57:24
    |
 LL |     let _: &dyn Sync = baz;
    |            ---------   ^^^ expected trait `Sync`, found trait `Baz`
@@ -32,7 +32,7 @@ LL |     let _: &dyn Sync = baz;
               found reference `&dyn Baz`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:61:25
+  --> $DIR/invalid-upcast.rs:60:25
    |
 LL |     let bar: &dyn Bar = baz;
    |              --------   ^^^ expected trait `Bar`, found trait `Baz`
@@ -43,7 +43,7 @@ LL |     let bar: &dyn Bar = baz;
               found reference `&dyn Baz`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:63:35
+  --> $DIR/invalid-upcast.rs:62:35
    |
 LL |     let _: &dyn std::fmt::Debug = bar;
    |            --------------------   ^^^ expected trait `Debug`, found trait `Bar`
@@ -54,7 +54,7 @@ LL |     let _: &dyn std::fmt::Debug = bar;
               found reference `&dyn Bar`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:65:24
+  --> $DIR/invalid-upcast.rs:64:24
    |
 LL |     let _: &dyn Send = bar;
    |            ---------   ^^^ expected trait `Send`, found trait `Bar`
@@ -65,7 +65,7 @@ LL |     let _: &dyn Send = bar;
               found reference `&dyn Bar`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:67:24
+  --> $DIR/invalid-upcast.rs:66:24
    |
 LL |     let _: &dyn Sync = bar;
    |            ---------   ^^^ expected trait `Sync`, found trait `Bar`
@@ -76,7 +76,7 @@ LL |     let _: &dyn Sync = bar;
               found reference `&dyn Bar`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:70:25
+  --> $DIR/invalid-upcast.rs:69:25
    |
 LL |     let foo: &dyn Foo = baz;
    |              --------   ^^^ expected trait `Foo`, found trait `Baz`
@@ -87,7 +87,7 @@ LL |     let foo: &dyn Foo = baz;
               found reference `&dyn Baz`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:72:35
+  --> $DIR/invalid-upcast.rs:71:35
    |
 LL |     let _: &dyn std::fmt::Debug = foo;
    |            --------------------   ^^^ expected trait `Debug`, found trait `Foo`
@@ -98,7 +98,7 @@ LL |     let _: &dyn std::fmt::Debug = foo;
               found reference `&dyn Foo`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:74:24
+  --> $DIR/invalid-upcast.rs:73:24
    |
 LL |     let _: &dyn Send = foo;
    |            ---------   ^^^ expected trait `Send`, found trait `Foo`
@@ -109,7 +109,7 @@ LL |     let _: &dyn Send = foo;
               found reference `&dyn Foo`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:76:24
+  --> $DIR/invalid-upcast.rs:75:24
    |
 LL |     let _: &dyn Sync = foo;
    |            ---------   ^^^ expected trait `Sync`, found trait `Foo`
@@ -120,7 +120,7 @@ LL |     let _: &dyn Sync = foo;
               found reference `&dyn Foo`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:79:25
+  --> $DIR/invalid-upcast.rs:78:25
    |
 LL |     let foo: &dyn Foo = bar;
    |              --------   ^^^ expected trait `Foo`, found trait `Bar`
@@ -131,7 +131,7 @@ LL |     let foo: &dyn Foo = bar;
               found reference `&dyn Bar`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:81:35
+  --> $DIR/invalid-upcast.rs:80:35
    |
 LL |     let _: &dyn std::fmt::Debug = foo;
    |            --------------------   ^^^ expected trait `Debug`, found trait `Foo`
@@ -142,7 +142,7 @@ LL |     let _: &dyn std::fmt::Debug = foo;
               found reference `&dyn Foo`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:83:24
+  --> $DIR/invalid-upcast.rs:82:24
    |
 LL |     let _: &dyn Send = foo;
    |            ---------   ^^^ expected trait `Send`, found trait `Foo`
@@ -153,7 +153,7 @@ LL |     let _: &dyn Send = foo;
               found reference `&dyn Foo`
 
 error[E0308]: mismatched types
-  --> $DIR/invalid-upcast.rs:85:24
+  --> $DIR/invalid-upcast.rs:84:24
    |
 LL |     let _: &dyn Sync = foo;
    |            ---------   ^^^ expected trait `Sync`, found trait `Foo`
diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
index 6d88002540c1a..b672963ae9887 100644
--- a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
+++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
@@ -1,6 +1,5 @@
 // run-pass
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 struct Test {
     func: Box<dyn FnMut() + 'static>,
diff --git a/src/test/ui/traits/trait-upcasting/lifetime.rs b/src/test/ui/traits/trait-upcasting/lifetime.rs
index f029a6f081f58..9825158c2dd38 100644
--- a/src/test/ui/traits/trait-upcasting/lifetime.rs
+++ b/src/test/ui/traits/trait-upcasting/lifetime.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
     fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
index 6986ad6217240..2e53a00a90e9c 100644
--- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.rs
@@ -1,12 +1,11 @@
 // check-fail
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Bar<T> {
     fn bar(&self, _: T) {}
 }
 
-trait Foo : Bar<i32> + Bar<u32> {
+trait Foo: Bar<i32> + Bar<u32> {
     fn foo(&self, _: ()) {}
 }
 
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
index 9564813512c4a..0ad18be03cdf9 100644
--- a/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurrence-ambiguousity.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/multiple-occurrence-ambiguousity.rs:21:26
+  --> $DIR/multiple-occurrence-ambiguousity.rs:20:26
    |
 LL |     let t: &dyn Bar<_> = s;
    |            -----------   ^ expected trait `Bar`, found trait `Foo`
diff --git a/src/test/ui/traits/trait-upcasting/replace-vptr.rs b/src/test/ui/traits/trait-upcasting/replace-vptr.rs
index 1164e43611a1d..9ccfc9306ac0c 100644
--- a/src/test/ui/traits/trait-upcasting/replace-vptr.rs
+++ b/src/test/ui/traits/trait-upcasting/replace-vptr.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait A {
     fn foo_a(&self);
diff --git a/src/test/ui/traits/trait-upcasting/struct.rs b/src/test/ui/traits/trait-upcasting/struct.rs
index 0f3cb285bf4c3..a3e41696956cb 100644
--- a/src/test/ui/traits/trait-upcasting/struct.rs
+++ b/src/test/ui/traits/trait-upcasting/struct.rs
@@ -1,7 +1,6 @@
 // run-pass
 
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 use std::rc::Rc;
 use std::sync::Arc;
diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.rs b/src/test/ui/traits/trait-upcasting/subtrait-method.rs
index 3508e15284bf2..136d15af0e8b2 100644
--- a/src/test/ui/traits/trait-upcasting/subtrait-method.rs
+++ b/src/test/ui/traits/trait-upcasting/subtrait-method.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
     fn a(&self) -> i32 {
diff --git a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
index af7a410f6d92c..918159e845b9e 100644
--- a/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
+++ b/src/test/ui/traits/trait-upcasting/subtrait-method.stderr
@@ -1,64 +1,64 @@
 error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
-  --> $DIR/subtrait-method.rs:56:9
+  --> $DIR/subtrait-method.rs:55:9
    |
 LL |     bar.c();
    |         ^ help: there is a method with a similar name: `a`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Baz` defines an item `c`, perhaps you need to implement it
-  --> $DIR/subtrait-method.rs:28:1
+  --> $DIR/subtrait-method.rs:27:1
    |
 LL | trait Baz: Bar {
    | ^^^^^^^^^^^^^^
 
 error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
-  --> $DIR/subtrait-method.rs:60:9
+  --> $DIR/subtrait-method.rs:59:9
    |
 LL |     foo.b();
    |         ^ help: there is a method with a similar name: `a`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Bar` defines an item `b`, perhaps you need to implement it
-  --> $DIR/subtrait-method.rs:18:1
+  --> $DIR/subtrait-method.rs:17:1
    |
 LL | trait Bar: Foo {
    | ^^^^^^^^^^^^^^
 
 error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
-  --> $DIR/subtrait-method.rs:62:9
+  --> $DIR/subtrait-method.rs:61:9
    |
 LL |     foo.c();
    |         ^ help: there is a method with a similar name: `a`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Baz` defines an item `c`, perhaps you need to implement it
-  --> $DIR/subtrait-method.rs:28:1
+  --> $DIR/subtrait-method.rs:27:1
    |
 LL | trait Baz: Bar {
    | ^^^^^^^^^^^^^^
 
 error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
-  --> $DIR/subtrait-method.rs:66:9
+  --> $DIR/subtrait-method.rs:65:9
    |
 LL |     foo.b();
    |         ^ help: there is a method with a similar name: `a`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Bar` defines an item `b`, perhaps you need to implement it
-  --> $DIR/subtrait-method.rs:18:1
+  --> $DIR/subtrait-method.rs:17:1
    |
 LL | trait Bar: Foo {
    | ^^^^^^^^^^^^^^
 
 error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
-  --> $DIR/subtrait-method.rs:68:9
+  --> $DIR/subtrait-method.rs:67:9
    |
 LL |     foo.c();
    |         ^ help: there is a method with a similar name: `a`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `Baz` defines an item `c`, perhaps you need to implement it
-  --> $DIR/subtrait-method.rs:28:1
+  --> $DIR/subtrait-method.rs:27:1
    |
 LL | trait Baz: Bar {
    | ^^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
index 79ddedd418756..6bc9f4a75d333 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo: Bar<i32> + Bar<u32> {}
 trait Bar<T> {
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
index 3985372119e88..fe269d8e99bf5 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -1,5 +1,5 @@
 error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
-  --> $DIR/type-checking-test-1.rs:17:13
+  --> $DIR/type-checking-test-1.rs:16:13
    |
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
    |             ^^^^^^^^^^^^^^^^ invalid cast
@@ -10,7 +10,7 @@ LL |     let _ = &x as &dyn Bar<_>; // Ambiguous
    |             +
 
 error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
-  --> $DIR/type-checking-test-1.rs:17:13
+  --> $DIR/type-checking-test-1.rs:16:13
    |
 LL |     let _ = x as &dyn Bar<_>; // Ambiguous
    |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
index 32754c5380378..36b11dffdb158 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo<T>: Bar<i32> + Bar<T> {}
 trait Bar<T> {
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
index 93c71f54eb53a..ef007d5cb909f 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -1,5 +1,5 @@
 error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
-  --> $DIR/type-checking-test-2.rs:20:13
+  --> $DIR/type-checking-test-2.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<u32>; // Error
    |             ^^^^^^^^^^^^^^^^^^ invalid cast
@@ -10,7 +10,7 @@ LL |     let _ = &x as &dyn Bar<u32>; // Error
    |             +
 
 error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
-  --> $DIR/type-checking-test-2.rs:20:13
+  --> $DIR/type-checking-test-2.rs:19:13
    |
 LL |     let _ = x as &dyn Bar<u32>; // Error
    |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
@@ -18,7 +18,7 @@ LL |     let _ = x as &dyn Bar<u32>; // Error
    = note: required for the cast from `&dyn Foo<i32>` to the object type `dyn Bar<u32>`
 
 error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
-  --> $DIR/type-checking-test-2.rs:26:13
+  --> $DIR/type-checking-test-2.rs:25:13
    |
 LL |     let a = x as &dyn Bar<_>; // Ambiguous
    |             ^^^^^^^^^^^^^^^^ invalid cast
@@ -29,7 +29,7 @@ LL |     let a = &x as &dyn Bar<_>; // Ambiguous
    |             +
 
 error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
-  --> $DIR/type-checking-test-2.rs:26:13
+  --> $DIR/type-checking-test-2.rs:25:13
    |
 LL |     let a = x as &dyn Bar<_>; // Ambiguous
    |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
index e48ba709af1fd..e6cb6a753998f 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.polonius.stderr
@@ -1,22 +1,18 @@
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-3.rs:13:13
+  --> $DIR/type-checking-test-3.rs:11:13
    |
 LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
 LL |     let _ = x as &dyn Bar<'a>; // Error
    |             ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
-   |
-   = help: consider replacing `'a` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-3.rs:18:13
+  --> $DIR/type-checking-test-3.rs:16:13
    |
 LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
    |                -- lifetime `'a` defined here
 LL |     let _ = x as &dyn Bar<'static>; // Error
    |             ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
-   |
-   = help: consider replacing `'a` with `'static`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
index b3aa2279a30a0..b2db3a127974c 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo<'a>: Bar<'a> {}
 trait Bar<'a> {}
@@ -10,12 +9,12 @@ fn test_correct(x: &dyn Foo<'static>) {
 
 fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
     let _ = x as &dyn Bar<'a>; // Error
-    //~^ ERROR lifetime may not live long enough
+                               //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong2<'a>(x: &dyn Foo<'a>) {
     let _ = x as &dyn Bar<'static>; // Error
-    //~^ ERROR lifetime may not live long enough
+                                    //~^ ERROR lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
index 5ad151b50924d..e6cb6a753998f 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-3.rs:12:13
+  --> $DIR/type-checking-test-3.rs:11:13
    |
 LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
@@ -7,7 +7,7 @@ LL |     let _ = x as &dyn Bar<'a>; // Error
    |             ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-3.rs:17:13
+  --> $DIR/type-checking-test-3.rs:16:13
    |
 LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
    |                -- lifetime `'a` defined here
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
index a3411f40ad0fb..8d506e5807ece 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.polonius.stderr
@@ -1,33 +1,52 @@
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:17:13
+  --> $DIR/type-checking-test-4.rs:15:13
    |
 LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
 LL |     let _ = x as &dyn Bar<'static, 'a>; // Error
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
-   |
-   = help: consider replacing `'a` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:22:13
+  --> $DIR/type-checking-test-4.rs:20:13
    |
 LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
 LL |     let _ = x as &dyn Bar<'a, 'static>; // Error
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
-   |
-   = help: consider replacing `'a` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:29:5
+  --> $DIR/type-checking-test-4.rs:26:5
    |
 LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                -- lifetime `'a` defined here
-...
+LL |     let y = x as &dyn Bar<'_, '_>;
 LL |     y.get_b() // ERROR
    |     ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/type-checking-test-4.rs:31:5
+   |
+LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                -- lifetime `'a` defined here
+LL |     <_ as Bar>::get_b(x) // ERROR
+   |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/type-checking-test-4.rs:36:5
+   |
+LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                -- lifetime `'a` defined here
+LL |     <_ as Bar<'_, '_>>::get_b(x) // ERROR
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/type-checking-test-4.rs:44:5
    |
-   = help: consider replacing `'a` with `'static`
+LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                -- lifetime `'a` defined here
+...
+LL |     z.get_b() // ERROR
+   |     ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
index 70ccc87fc3e14..f40c48f0d125f 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
@@ -1,5 +1,4 @@
 #![feature(trait_upcasting)]
-#![allow(incomplete_features)]
 
 trait Foo<'a>: Bar<'a, 'a> {}
 trait Bar<'a, 'b> {
@@ -14,28 +13,28 @@ fn test_correct(x: &dyn Foo<'static>) {
 
 fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
     let _ = x as &dyn Bar<'static, 'a>; // Error
-    //~^ ERROR lifetime may not live long enough
+                                        //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
     let _ = x as &dyn Bar<'a, 'static>; // Error
-    //~^ ERROR lifetime may not live long enough
+                                        //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
     let y = x as &dyn Bar<'_, '_>;
     y.get_b() // ERROR
-    //~^ ERROR lifetime may not live long enough
+              //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
     <_ as Bar>::get_b(x) // ERROR
-    //~^ ERROR lifetime may not live long enough
+                         //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
     <_ as Bar<'_, '_>>::get_b(x) // ERROR
-    //~^ ERROR lifetime may not live long enough
+                                 //~^ ERROR lifetime may not live long enough
 }
 
 fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
@@ -43,7 +42,7 @@ fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
     y.get_b(); // ERROR
     let z = y;
     z.get_b() // ERROR
-    //~^ ERROR lifetime may not live long enough
+              //~^ ERROR lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
index 436129d0bee52..8d506e5807ece 100644
--- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:16:13
+  --> $DIR/type-checking-test-4.rs:15:13
    |
 LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
@@ -7,7 +7,7 @@ LL |     let _ = x as &dyn Bar<'static, 'a>; // Error
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:21:13
+  --> $DIR/type-checking-test-4.rs:20:13
    |
 LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
    |                -- lifetime `'a` defined here
@@ -15,7 +15,7 @@ LL |     let _ = x as &dyn Bar<'a, 'static>; // Error
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:27:5
+  --> $DIR/type-checking-test-4.rs:26:5
    |
 LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                -- lifetime `'a` defined here
@@ -24,7 +24,7 @@ LL |     y.get_b() // ERROR
    |     ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:32:5
+  --> $DIR/type-checking-test-4.rs:31:5
    |
 LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                -- lifetime `'a` defined here
@@ -32,7 +32,7 @@ LL |     <_ as Bar>::get_b(x) // ERROR
    |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:37:5
+  --> $DIR/type-checking-test-4.rs:36:5
    |
 LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                -- lifetime `'a` defined here
@@ -40,7 +40,7 @@ LL |     <_ as Bar<'_, '_>>::get_b(x) // ERROR
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/type-checking-test-4.rs:45:5
+  --> $DIR/type-checking-test-4.rs:44:5
    |
 LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
    |                -- lifetime `'a` defined here
diff --git a/src/tools/cargo b/src/tools/cargo
index 9286a1beba5b2..a3dfea71ca0c8 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 9286a1beba5b28b115bad67de2ae91fb1c61eb0b
+Subproject commit a3dfea71ca0c888a88111086898aa833c291d497