diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 356e9fef439..6414c8e9041 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -15,7 +15,7 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(negative_impls)]
 #![feature(stmt_expr_attributes)]
 
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index 37e45379ba9..e87cf05713c 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -8,6 +8,10 @@ ast_lowering_arbitrary_expression_in_pattern =
 
 ast_lowering_argument = argument
 
+ast_lowering_assoc_ty_binding_in_dyn =
+    associated type bounds are not allowed in `dyn` types
+    .suggestion = use `impl Trait` to introduce a type instead
+
 ast_lowering_assoc_ty_parentheses =
     parenthesized generic arguments cannot be used in associated type constraints
 
@@ -100,9 +104,6 @@ ast_lowering_match_arm_with_no_body =
     `match` arm with no body
     .suggestion = add a body after the pattern
 
-ast_lowering_misplaced_assoc_ty_binding =
-    associated type bounds are only allowed in where clauses and function signatures, not in {$position}
-
 ast_lowering_misplaced_double_dot =
     `..` patterns are not allowed here
     .note = only allowed in tuple, tuple struct, and slice patterns
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 62253585695..274e6b7458c 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -94,11 +94,12 @@ pub struct MisplacedImplTrait<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_lowering_misplaced_assoc_ty_binding)]
-pub struct MisplacedAssocTyBinding<'a> {
+#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
+pub struct MisplacedAssocTyBinding {
     #[primary_span]
     pub span: Span,
-    pub position: DiagnosticArgFromDisplay<'a>,
+    #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
+    pub suggestion: Option<Span>,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 4ef9c7607be..5f7439060b3 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -197,7 +197,6 @@ trait ResolverAstLoweringExt {
     fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
     fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
     fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
-    fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId);
 }
 
 impl ResolverAstLoweringExt for ResolverAstLowering {
@@ -256,11 +255,6 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
     fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
         self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
     }
-
-    fn remap_extra_lifetime_params(&mut self, from: NodeId, to: NodeId) {
-        let lifetimes = self.extra_lifetime_params_map.remove(&from).unwrap_or_default();
-        self.extra_lifetime_params_map.insert(to, lifetimes);
-    }
 }
 
 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
@@ -1084,88 +1078,38 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::TypeBindingKind::Equality { term }
             }
             AssocConstraintKind::Bound { bounds } => {
-                enum DesugarKind {
-                    ImplTrait,
-                    Error(ImplTraitPosition),
-                    Bound,
-                }
+                // Disallow ATB in dyn types
+                if self.is_in_dyn_type {
+                    let suggestion = match itctx {
+                        ImplTraitContext::ReturnPositionOpaqueTy { .. }
+                        | ImplTraitContext::TypeAliasesOpaqueTy { .. }
+                        | ImplTraitContext::Universal => {
+                            let bound_end_span = constraint
+                                .gen_args
+                                .as_ref()
+                                .map_or(constraint.ident.span, |args| args.span());
+                            if bound_end_span.eq_ctxt(constraint.span) {
+                                Some(self.tcx.sess.source_map().next_point(bound_end_span))
+                            } else {
+                                None
+                            }
+                        }
+                        _ => None,
+                    };
 
-                // Piggy-back on the `impl Trait` context to figure out the correct behavior.
-                let desugar_kind = match itctx {
-                    // in an argument, RPIT, or TAIT, if we are within a dyn type:
-                    //
-                    //     fn foo(x: dyn Iterator<Item: Debug>)
-                    //
-                    // then desugar to:
-                    //
-                    //     fn foo(x: dyn Iterator<Item = impl Debug>)
-                    //
-                    // This is because dyn traits must have all of their associated types specified.
-                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                    | ImplTraitContext::TypeAliasesOpaqueTy { .. }
-                    | ImplTraitContext::Universal
-                        if self.is_in_dyn_type =>
-                    {
-                        DesugarKind::ImplTrait
-                    }
+                    let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
+                        span: constraint.span,
+                        suggestion,
+                    });
+                    let err_ty =
+                        &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
+                    hir::TypeBindingKind::Equality { term: err_ty.into() }
+                } else {
+                    // Desugar `AssocTy: Bounds` into a type binding where the
+                    // later desugars into a trait predicate.
+                    let bounds = self.lower_param_bounds(bounds, itctx);
 
-                    ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
-                        DesugarKind::Error(position)
-                    }
-
-                    // We are in the parameter position, but not within a dyn type:
-                    //
-                    //     fn foo(x: impl Iterator<Item: Debug>)
-                    //
-                    // so we leave it as is and this gets expanded in astconv to a bound like
-                    // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
-                    // `impl Iterator`.
-                    _ => DesugarKind::Bound,
-                };
-
-                match desugar_kind {
-                    DesugarKind::ImplTrait => {
-                        // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
-                        // constructing the HIR for `impl bounds...` and then lowering that.
-
-                        let impl_trait_node_id = self.next_node_id();
-                        // Shift `impl Trait` lifetime captures from the associated type bound's
-                        // node id to the opaque node id, so that the opaque can actually use
-                        // these lifetime bounds.
-                        self.resolver
-                            .remap_extra_lifetime_params(constraint.id, impl_trait_node_id);
-
-                        self.with_dyn_type_scope(false, |this| {
-                            let node_id = this.next_node_id();
-                            let ty = this.lower_ty(
-                                &Ty {
-                                    id: node_id,
-                                    kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
-                                    span: this.lower_span(constraint.span),
-                                    tokens: None,
-                                },
-                                itctx,
-                            );
-
-                            hir::TypeBindingKind::Equality { term: ty.into() }
-                        })
-                    }
-                    DesugarKind::Bound => {
-                        // Desugar `AssocTy: Bounds` into a type binding where the
-                        // later desugars into a trait predicate.
-                        let bounds = self.lower_param_bounds(bounds, itctx);
-
-                        hir::TypeBindingKind::Constraint { bounds }
-                    }
-                    DesugarKind::Error(position) => {
-                        let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
-                            span: constraint.span,
-                            position: DiagnosticArgFromDisplay(&position),
-                        });
-                        let err_ty =
-                            &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
-                        hir::TypeBindingKind::Equality { term: err_ty.into() }
-                    }
+                    hir::TypeBindingKind::Constraint { bounds }
                 }
             }
         };
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index de96bf477ad..e688e84db61 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -13,7 +13,6 @@
 #![feature(hash_raw_entry)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
 #![feature(impl_trait_in_assoc_type)]
 
 #[macro_use]
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index a80f6a1add0..fa7719d8971 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -190,6 +190,8 @@ codegen_ssa_no_module_named =
 
 codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
 
+codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't
+
 codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
     .note = {$output}
 
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 9b24339d255..a63642d76b9 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -913,7 +913,9 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
 
     let object = load_from_incr_comp_dir(
         cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)),
-        module.source.saved_files.get("o").expect("no saved object file in work product"),
+        module.source.saved_files.get("o").unwrap_or_else(|| {
+            cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
+        }),
     );
     let dwarf_object =
         module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 06ea5b9e8f4..3d7903b5efb 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -121,6 +121,12 @@ pub struct NoNatvisDirectory {
     pub error: Error,
 }
 
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_no_saved_object_file)]
+pub struct NoSavedObjectFile<'a> {
+    pub cgu_name: &'a str,
+}
+
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_copy_path_buf)]
 pub struct CopyPathBuf {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index ee3f349c6b8..28dc69859fd 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -449,35 +449,27 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 }
             }
 
-            Rvalue::Ref(_, BorrowKind::Mut { .. }, place) => {
-                let ty = place.ty(self.body, self.tcx).ty;
-                let is_allowed = match ty.kind() {
-                    // Inside a `static mut`, `&mut [...]` is allowed.
-                    ty::Array(..) | ty::Slice(_)
-                        if self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut) =>
-                    {
-                        true
-                    }
-
-                    // FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given
-                    // that this is merely a ZST and it is already eligible for promotion.
-                    // This may require an RFC?
-                    /*
-                    ty::Array(_, len) if len.try_eval_target_usize(cx.tcx, cx.param_env) == Some(0)
-                        => true,
-                    */
-                    _ => false,
-                };
+            Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
+            | Rvalue::AddressOf(Mutability::Mut, place) => {
+                // Inside mutable statics, we allow arbitrary mutable references.
+                // We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
+                // reasons why are lost to history), and there is no reason to restrict that to
+                // arrays and slices.
+                let is_allowed =
+                    self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut);
 
                 if !is_allowed {
-                    self.check_mut_borrow(place.local, hir::BorrowKind::Ref)
+                    self.check_mut_borrow(
+                        place.local,
+                        if matches!(rvalue, Rvalue::Ref(..)) {
+                            hir::BorrowKind::Ref
+                        } else {
+                            hir::BorrowKind::Raw
+                        },
+                    );
                 }
             }
 
-            Rvalue::AddressOf(Mutability::Mut, place) => {
-                self.check_mut_borrow(place.local, hir::BorrowKind::Raw)
-            }
-
             Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake, place)
             | Rvalue::AddressOf(Mutability::Not, place) => {
                 let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 7216fa8f5e4..ab3ad0e9d68 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -7,6 +7,7 @@
 #![allow(internal_features)]
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(array_windows)]
@@ -16,7 +17,6 @@
 #![feature(error_reporter)]
 #![feature(extract_if)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index aff946ac580..9921686ce28 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,7 +5,7 @@
 #![feature(associated_type_defaults)]
 #![feature(closure_track_caller)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 50809a571b8..7250dc81faf 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1283,7 +1283,8 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
     let ty = tcx.type_of(def_id).instantiate_identity();
     if ty.references_error() {
         // If there is already another error, do not emit an error for not using a type parameter.
-        assert!(tcx.dcx().has_errors().is_some());
+        // Without the `stashed_err_count` part this can fail (#120856).
+        assert!(tcx.dcx().has_errors().is_some() || tcx.dcx().stashed_err_count() > 0);
         return;
     }
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 8cf1f2c9407..817dab993a3 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -10,7 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
-use rustc_span::ErrorGuaranteed;
+use rustc_span::{sym, ErrorGuaranteed};
 use rustc_trait_selection::traits;
 
 mod builtin;
@@ -70,7 +70,11 @@ fn enforce_trait_manually_implementable(
     if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable =
         tcx.trait_def(trait_def_id).specialization_kind
     {
-        if !tcx.features().specialization && !tcx.features().min_specialization {
+        if !tcx.features().specialization
+            && !tcx.features().min_specialization
+            && !impl_header_span.allows_unstable(sym::specialization)
+            && !impl_header_span.allows_unstable(sym::min_specialization)
+        {
             return Err(tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span }));
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 883d416ecd1..1aaefc5b520 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -67,7 +67,7 @@ This API is completely unstable and subject to change.
 #![feature(is_sorted)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(never_type)]
 #![feature(lazy_cell)]
 #![feature(slice_partition_dedup)]
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 315dc4330ad..06a14613567 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -5,7 +5,7 @@
 #![feature(try_blocks)]
 #![feature(never_type)]
 #![feature(box_patterns)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(control_flow_enum)]
 
 #[macro_use]
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 622cdf0c7b8..97f9a4b291d 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -24,7 +24,7 @@
 #![feature(let_chains)]
 #![feature(if_let_guard)]
 #![feature(iterator_try_collect)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(try_blocks)]
 #![recursion_limit = "512"] // For rustdoc
 
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5c2a422a2b7..5f769e9ad8a 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -35,7 +35,6 @@
 #![feature(iter_order_by)]
 #![feature(let_chains)]
 #![feature(trait_upcasting)]
-#![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![allow(internal_features)]
 
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 8b7e82d2113..7ed78a2ffc8 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,5 +1,3 @@
-#![feature(min_specialization)]
-
 #[macro_use]
 extern crate rustc_macros;
 
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 43e44b47e3f..e3f202b7f18 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -9,7 +9,7 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(try_blocks)]
 
 #[macro_use]
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index a4b58e5bfc1..f18a2354301 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -2,7 +2,7 @@
 #![feature(box_patterns)]
 #![feature(exact_size_is_empty)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(try_blocks)]
 
 #[macro_use]
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 8e5d69605aa..ad0cd4fcff9 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -8,7 +8,7 @@
 #![feature(is_sorted)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(never_type)]
 #![feature(option_get_or_insert_default)]
 #![feature(round_char_boundary)]
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 064af5aec35..e795537e84a 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -10,7 +10,6 @@
 #![allow(internal_features)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
-#![feature(min_specialization)]
 #![feature(try_blocks)]
 
 #[macro_use]
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index b19c5b6f28f..04c5e60aa6b 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -14,7 +14,7 @@
 #![feature(exhaustive_patterns)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![feature(rustc_attrs)]
 #![feature(step_trait)]
 #![allow(internal_features)]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 053ecfc681c..00a2adccf64 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -24,7 +24,7 @@
 #![feature(option_take_if)]
 #![feature(never_type)]
 #![feature(type_alias_impl_trait)]
-#![feature(min_specialization)]
+#![cfg_attr(bootstrap, feature(min_specialization))]
 #![recursion_limit = "512"] // For rustdoc
 
 #[macro_use]
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index ecc0613d7b9..e11d13f8bed 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -1157,8 +1157,13 @@ impl str {
     ///
     /// Returns `false` if it does not.
     ///
-    /// The [pattern] can be a `&str`, [`char`], a slice of [`char`]s, or a
+    /// The [pattern] can be a `&str`, in which case this function will return true if
+    /// the `&str` is a prefix of this string slice.
+    ///
+    /// The [pattern] can also be a [`char`], a slice of [`char`]s, or a
     /// function or closure that determines if a character matches.
+    /// These will only be checked against the first character of this string slice.
+    /// Look at the second example below regarding behavior for slices of [`char`]s.
     ///
     /// [`char`]: prim@char
     /// [pattern]: self::pattern
@@ -1171,6 +1176,14 @@ impl str {
     /// assert!(bananas.starts_with("bana"));
     /// assert!(!bananas.starts_with("nana"));
     /// ```
+    ///
+    /// ```
+    /// let bananas = "bananas";
+    ///
+    /// // Note that both of these assert successfully.
+    /// assert!(bananas.starts_with(&['b', 'a', 'n', 'a']));
+    /// assert!(bananas.starts_with(&['a', 'b', 'c', 'd']));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
         pat.is_prefix_of(self)
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index ad8c70c6a3c..d9654973b84 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -2119,7 +2119,16 @@ macro_rules! atomic_int {
         /// This type has the same in-memory representation as the underlying
         /// integer type, [`
         #[doc = $s_int_type]
-        /// `]. For more about the differences between atomic types and
+        /// `].
+        #[doc = if_not_8_bit! {
+            $int_type,
+            concat!(
+                "However, the alignment of this type is always equal to its ",
+                "size, even on targets where [`", $s_int_type, "`] has a ",
+                "lesser alignment."
+            )
+        }]
+        /// For more about the differences between atomic types and
         /// non-atomic types as well as information about the portability of
         /// this type, please see the [module-level documentation].
         ///
diff --git a/tests/ui/array-slice-vec/check-static-mut-slices.rs b/tests/ui/array-slice-vec/check-static-mut-slices.rs
deleted file mode 100644
index b89c634036e..00000000000
--- a/tests/ui/array-slice-vec/check-static-mut-slices.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-#![allow(dead_code)]
-
-// Checks that mutable static items can have mutable slices
-
-
-static mut TEST: &'static mut [isize] = &mut [1];
-static mut EMPTY: &'static mut [isize] = &mut [];
-
-pub fn main() {
-    unsafe {
-        TEST[0] += 1;
-        assert_eq!(TEST[0], 2);
-    }
-}
diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
index 4c36289f47b..8a580e19186 100644
--- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
+++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs
@@ -28,9 +28,9 @@ impl Bar for AssocNoCopy {
 
 impl Thing for AssocNoCopy {
     type Out = Box<dyn Bar<Assoc: Copy>>;
+    //~^ ERROR associated type bounds are not allowed in `dyn` types
 
     fn func() -> Self::Out {
-        //~^ ERROR the trait bound `String: Copy` is not satisfied
         Box::new(AssocNoCopy)
     }
 }
diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
index 7942992874d..ad540909411 100644
--- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
+++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr
@@ -1,9 +1,13 @@
-error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:32:18
+error: associated type bounds are not allowed in `dyn` types
+  --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28
    |
-LL |     fn func() -> Self::Out {
-   |                  ^^^^^^^^^ the trait `Copy` is not implemented for `String`
+LL |     type Out = Box<dyn Bar<Assoc: Copy>>;
+   |                            ^^^^^^^^^^^
+   |
+help: use `impl Trait` to introduce a type instead
+   |
+LL |     type Out = Box<dyn Bar<Assoc = impl Copy>>;
+   |                                  ~~~~~~
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
index 8cab1f66c27..81c8fe829f9 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
@@ -7,7 +7,7 @@ trait B {
 fn f()
 where
     dyn for<'j> B<AssocType: 'j>:,
-    //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+    //~^ ERROR associated type bounds are not allowed in `dyn` types
 {
 }
 
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
index fe300a7de42..7d9870c72d4 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
@@ -1,4 +1,4 @@
-error: associated type bounds are only allowed in where clauses and function signatures, not in bounds
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:19
    |
 LL |     dyn for<'j> B<AssocType: 'j>:,
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
index 1d5d181efcc..f465123f34c 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
+++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
@@ -8,6 +8,6 @@ trait Trait2 {}
 
 // It's not possible to insert a universal `impl Trait` here!
 impl dyn Trait<Item: Trait2> {}
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr
index 7bdb2c5a7c2..8855bd9c312 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr
+++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr
@@ -1,4 +1,4 @@
-error: associated type bounds are only allowed in where clauses and function signatures, not in impl headers
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/bad-universal-in-impl-sig.rs:10:16
    |
 LL | impl dyn Trait<Item: Trait2> {}
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
index 036f8ede1b3..54c8cd3fde0 100644
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ b/tests/ui/associated-type-bounds/duplicate.rs
@@ -261,11 +261,4 @@ trait TRA3 {
     //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
 }
 
-type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index bf6aab96dc7..9816d11a40a 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -6,30 +6,6 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
    |                        |
    |                        `Item` bound here first
 
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:264:40
-   |
-LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
-   |                            ----------  ^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:266:44
-   |
-LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
-   |                                ----------  ^^^^^^^^^^ re-bound here
-   |                                |
-   |                                `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:268:43
-   |
-LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
-   |                            -------------  ^^^^^^^^^^^^^ re-bound here
-   |                            |
-   |                            `Item` bound here first
-
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
   --> $DIR/duplicate.rs:11:36
    |
@@ -631,7 +607,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 75 previous errors
+error: aborting due to 72 previous errors
 
 Some errors have detailed explanations: E0282, E0719.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs
deleted file mode 100644
index 079c44b3a59..00000000000
--- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-// run-pass
-
-#![feature(associated_type_bounds)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-type Et1 = Box<dyn Tr1<As1: Copy>>;
-fn def_et1() -> Et1 { Box::new(S1) }
-pub fn use_et1() { assert_copy(def_et1().mk()); }
-
-type Et2 = Box<dyn Tr1<As1: 'static>>;
-fn def_et2() -> Et2 { Box::new(S1) }
-pub fn use_et2() { assert_static(def_et2().mk()); }
-
-type Et3 = Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>>;
-fn def_et3() -> Et3 {
-    struct A;
-    impl Tr1 for A {
-        type As1 = core::ops::Range<u8>;
-        fn mk(&self) -> Self::As1 { 0..10 }
-    }
-    Box::new(A)
-}
-pub fn use_et3() {
-    let _0 = def_et3().mk().clone();
-    let mut s = 0u8;
-    for _1 in _0 {
-        let _2 = _1 + 1u8;
-        s += _2.into();
-    }
-    assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-type Et4 = Box<dyn Tr1<As1: for<'a> Tr2<'a>>>;
-fn def_et4() -> Et4 {
-    #[derive(Copy, Clone)]
-    struct A;
-    impl Tr1 for A {
-        type As1 = A;
-        fn mk(&self) -> A { A }
-    }
-    impl<'a> Tr2<'a> for A {
-        fn tr2(self) -> &'a Self { &A }
-    }
-    Box::new(A)
-}
-pub fn use_et4() { assert_forall_tr2(def_et4().mk()); }
-
-fn main() {
-    use_et1();
-    use_et2();
-    use_et3();
-    use_et4();
-}
diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr b/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr
deleted file mode 100644
index 2e26a434f5d..00000000000
--- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: method `tr2` is never used
-  --> $DIR/dyn-impl-trait-type.rs:8:20
-   |
-LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-   |       ---          ^^^
-   |       |
-   |       method in this trait
-   |
-   = note: `#[warn(dead_code)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs
deleted file mode 100644
index 49e5e72f225..00000000000
--- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-// run-pass
-
-// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed.
-
-#![feature(associated_type_bounds)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-fn def_et1() -> Box<dyn Tr1<As1: Copy>> {
-    let x /* : Box<dyn Tr1<As1: Copy>> */ = Box::new(S1);
-    x
-}
-pub fn use_et1() { assert_copy(def_et1().mk()); }
-
-fn def_et2() -> Box<dyn Tr1<As1: Send + 'static>> {
-    let x /* : Box<dyn Tr1<As1: Send + 'static>> */ = Box::new(S1);
-    x
-}
-pub fn use_et2() { assert_static(def_et2().mk()); }
-
-fn def_et3() -> Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>> {
-    struct A;
-    impl Tr1 for A {
-        type As1 = core::ops::Range<u8>;
-        fn mk(&self) -> Self::As1 { 0..10 }
-    }
-    let x /* : Box<dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>>> */
-        = Box::new(A);
-    x
-}
-pub fn use_et3() {
-    let _0 = def_et3().mk().clone();
-    let mut s = 0u8;
-    for _1 in _0 {
-        let _2 = _1 + 1u8;
-        s += _2.into();
-    }
-    assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-fn def_et4() -> Box<dyn Tr1<As1: for<'a> Tr2<'a>>> {
-    #[derive(Copy, Clone)]
-    struct A;
-    impl Tr1 for A {
-        type As1 = A;
-        fn mk(&self) -> A { A }
-    }
-    impl<'a> Tr2<'a> for A {
-        fn tr2(self) -> &'a Self { &A }
-    }
-    let x /* : Box<dyn Tr1<As1: for<'a> Tr2<'a>>> */ = Box::new(A);
-    x
-}
-pub fn use_et4() { assert_forall_tr2(def_et4().mk()); }
-
-fn main() {
-    use_et1();
-    use_et2();
-    use_et3();
-    use_et4();
-}
diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr b/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr
deleted file mode 100644
index 9eddbe46284..00000000000
--- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-warning: method `tr2` is never used
-  --> $DIR/dyn-rpit-and-let.rs:10:20
-   |
-LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-   |       ---          ^^^
-   |       |
-   |       method in this trait
-   |
-   = note: `#[warn(dead_code)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/associated-type-bounds/elision.rs b/tests/ui/associated-type-bounds/elision.rs
index d00def57166..5d7ed940ac6 100644
--- a/tests/ui/associated-type-bounds/elision.rs
+++ b/tests/ui/associated-type-bounds/elision.rs
@@ -3,7 +3,7 @@
 
 // The same thing should happen for constraints in dyn trait.
 fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
-//~^ ERROR missing lifetime specifier
-//~| ERROR mismatched types
+//~^ ERROR associated type bounds are not allowed in `dyn` types
+//~| ERROR missing lifetime specifier
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr
index a29e32a784f..749dffdc4d3 100644
--- a/tests/ui/associated-type-bounds/elision.stderr
+++ b/tests/ui/associated-type-bounds/elision.stderr
@@ -10,19 +10,17 @@ help: consider introducing a named lifetime parameter
 LL | fn f<'a>(x: &'a mut dyn Iterator<Item: Iterator<Item = &'a ()>>) -> Option<&'a ()> { x.next() }
    |     ++++     ++                                         ~~                  ~~
 
-error[E0308]: mismatched types
-  --> $DIR/elision.rs:5:79
+error: associated type bounds are not allowed in `dyn` types
+  --> $DIR/elision.rs:5:27
    |
 LL | fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
-   |                           -----------------------------      --------------   ^^^^^^^^ expected `Option<&()>`, found `Option<impl Iterator<Item = &'_ ()>>`
-   |                           |                                  |
-   |                           |                                  expected `Option<&()>` because of return type
-   |                           found this type parameter
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected enum `Option<&()>`
-              found enum `Option<impl Iterator<Item = &'_ ()>>`
+help: use `impl Trait` to introduce a type instead
+   |
+LL | fn f(x: &mut dyn Iterator<Item = impl Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
+   |                                ~~~~~~
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0106, E0308.
-For more information about an error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/associated-type-bounds/fn-dyn-apit.rs b/tests/ui/associated-type-bounds/fn-dyn-apit.rs
deleted file mode 100644
index c4e8092c211..00000000000
--- a/tests/ui/associated-type-bounds/fn-dyn-apit.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-// run-pass
-// aux-build:fn-dyn-aux.rs
-
-#![allow(unused)]
-#![feature(associated_type_bounds)]
-
-extern crate fn_dyn_aux;
-
-use fn_dyn_aux::*;
-
-// ATB, APIT (dyn trait):
-
-fn dyn_apit_bound(beta: &dyn Beta<Gamma: Alpha>) -> usize {
-    desugared_bound(beta)
-}
-
-fn dyn_apit_bound_region(beta: &dyn Beta<Gamma: 'static>) -> usize {
-    desugared_bound_region(beta)
-}
-
-fn dyn_apit_bound_multi(
-    beta: &(dyn Beta<Gamma: Alpha + 'static + Delta> + Send)
-) -> usize {
-    desugared_bound_multi(beta)
-}
-
-fn dyn_apit_bound_region_forall(
-    beta: &dyn Beta<Gamma: Copy + for<'a> Epsilon<'a>>
-) -> usize {
-    desugared_bound_region_forall(beta)
-}
-
-fn dyn_apit_bound_region_forall2(
-    beta: &dyn Beta<Gamma: Copy + for<'a> Epsilon<'a, Zeta: Eta>>
-) -> usize {
-    desugared_bound_region_forall2(beta)
-}
-
-fn dyn_apit_bound_nested(
-    beta: &dyn Beta<Gamma: Copy + Alpha + Beta<Gamma: Delta>>
-) -> usize {
-    desugared_bound_nested(beta)
-}
-
-fn dyn_apit_bound_nested2(
-    beta: &dyn Beta<Gamma = impl Copy + Alpha + Beta<Gamma: Delta>>
-) -> usize {
-    desugared_bound_nested(beta)
-}
-
-fn main() {
-    let beta = BetaType;
-    let _gamma = beta.gamma();
-
-    assert_eq!(42, dyn_apit_bound(&beta));
-    assert_eq!(24, dyn_apit_bound_region(&beta));
-    assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta));
-    assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta));
-    assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta));
-    assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta));
-}
diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs
index 057966941dc..2b4b060983e 100644
--- a/tests/ui/associated-type-bounds/inside-adt.rs
+++ b/tests/ui/associated-type-bounds/inside-adt.rs
@@ -3,24 +3,24 @@
 use std::mem::ManuallyDrop;
 
 struct S1 { f: dyn Iterator<Item: Copy> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 struct S2 { f: Box<dyn Iterator<Item: Copy>> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 struct S3 { f: dyn Iterator<Item: 'static> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 
 enum E1 { V(dyn Iterator<Item: Copy>) }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 enum E3 { V(dyn Iterator<Item: 'static>) }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 
 union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
-//~^ ERROR associated type bounds are only allowed in where clauses and function signatures
+//~^ ERROR associated type bounds are not allowed in `dyn` types
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr
index f848bd798ee..ef45fae8f2a 100644
--- a/tests/ui/associated-type-bounds/inside-adt.stderr
+++ b/tests/ui/associated-type-bounds/inside-adt.stderr
@@ -1,52 +1,52 @@
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:5:29
    |
 LL | struct S1 { f: dyn Iterator<Item: Copy> }
    |                             ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:7:33
    |
 LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                 ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:9:29
    |
 LL | struct S3 { f: dyn Iterator<Item: 'static> }
    |                             ^^^^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:12:26
    |
 LL | enum E1 { V(dyn Iterator<Item: Copy>) }
    |                          ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:14:30
    |
 LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
    |                              ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:16:26
    |
 LL | enum E3 { V(dyn Iterator<Item: 'static>) }
    |                          ^^^^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:19:41
    |
 LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
    |                                         ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:21:45
    |
 LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
    |                                             ^^^^^^^^^^
 
-error: associated type bounds are only allowed in where clauses and function signatures, not in field types
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/inside-adt.rs:23:41
    |
 LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
diff --git a/tests/ui/associated-type-bounds/issue-104916.rs b/tests/ui/associated-type-bounds/issue-104916.rs
index 3361fa011ed..ee29a0a2fc4 100644
--- a/tests/ui/associated-type-bounds/issue-104916.rs
+++ b/tests/ui/associated-type-bounds/issue-104916.rs
@@ -7,7 +7,7 @@ trait B {
 fn f()
 where
     dyn for<'j> B<AssocType: 'j>:,
-    //~^ ERROR: associated type bounds are only allowed in where clauses and function signatures
+    //~^ ERROR: associated type bounds are not allowed in `dyn` types
 {
 }
 
diff --git a/tests/ui/associated-type-bounds/issue-104916.stderr b/tests/ui/associated-type-bounds/issue-104916.stderr
index 65c89735c5d..e8618b72103 100644
--- a/tests/ui/associated-type-bounds/issue-104916.stderr
+++ b/tests/ui/associated-type-bounds/issue-104916.stderr
@@ -1,4 +1,4 @@
-error: associated type bounds are only allowed in where clauses and function signatures, not in bounds
+error: associated type bounds are not allowed in `dyn` types
   --> $DIR/issue-104916.rs:9:19
    |
 LL |     dyn for<'j> B<AssocType: 'j>:,
diff --git a/tests/ui/consts/const-address-of-mut.rs b/tests/ui/consts/const-address-of-mut.rs
index 5f0c76d6285..0018bf18e41 100644
--- a/tests/ui/consts/const-address-of-mut.rs
+++ b/tests/ui/consts/const-address-of-mut.rs
@@ -4,8 +4,6 @@ const A: () = { let mut x = 2; &raw mut x; };           //~ mutable pointer
 
 static B: () = { let mut x = 2; &raw mut x; };          //~ mutable pointer
 
-static mut C: () = { let mut x = 2; &raw mut x; };      //~ mutable pointer
-
 const fn foo() {
     let mut x = 0;
     let y = &raw mut x;                                 //~ mutable pointer
diff --git a/tests/ui/consts/const-address-of-mut.stderr b/tests/ui/consts/const-address-of-mut.stderr
index 1b371fcee98..95a91ff463f 100644
--- a/tests/ui/consts/const-address-of-mut.stderr
+++ b/tests/ui/consts/const-address-of-mut.stderr
@@ -18,18 +18,8 @@ LL | static B: () = { let mut x = 2; &raw mut x; };
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: raw mutable pointers are not allowed in statics
-  --> $DIR/const-address-of-mut.rs:7:37
-   |
-LL | static mut C: () = { let mut x = 2; &raw mut x; };
-   |                                     ^^^^^^^^^^
-   |
-   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
-   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error[E0658]: raw mutable pointers are not allowed in constant functions
-  --> $DIR/const-address-of-mut.rs:11:13
+  --> $DIR/const-address-of-mut.rs:9:13
    |
 LL |     let y = &raw mut x;
    |             ^^^^^^^^^^
@@ -38,6 +28,6 @@ LL |     let y = &raw mut x;
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
index 2df80020fdc..4793466a987 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references_err.32bit.stderr
@@ -133,11 +133,6 @@ help: skipping check for `const_mut_refs` feature
    |
 LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: skipping check that does not even have a feature gate
-  --> $DIR/mutable_references_err.rs:40:49
-   |
-LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
   --> $DIR/mutable_references_err.rs:47:44
    |
@@ -148,11 +143,6 @@ help: skipping check that does not even have a feature gate
    |
 LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
    |                                            ^^^^^^^
-help: skipping check that does not even have a feature gate
-  --> $DIR/mutable_references_err.rs:50:36
-   |
-LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
-   |                                    ^^^^^^^
 help: skipping check that does not even have a feature gate
   --> $DIR/mutable_references_err.rs:51:45
    |
diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
index 3ff6811ea61..f5f7b605c94 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references_err.64bit.stderr
@@ -133,11 +133,6 @@ help: skipping check for `const_mut_refs` feature
    |
 LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: skipping check that does not even have a feature gate
-  --> $DIR/mutable_references_err.rs:40:49
-   |
-LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: skipping check that does not even have a feature gate
   --> $DIR/mutable_references_err.rs:47:44
    |
@@ -148,11 +143,6 @@ help: skipping check that does not even have a feature gate
    |
 LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
    |                                            ^^^^^^^
-help: skipping check that does not even have a feature gate
-  --> $DIR/mutable_references_err.rs:50:36
-   |
-LL | static mut MUTABLE_REF: &mut i32 = &mut 42;
-   |                                    ^^^^^^^
 help: skipping check that does not even have a feature gate
   --> $DIR/mutable_references_err.rs:51:45
    |
diff --git a/tests/ui/consts/static-mut-refs.rs b/tests/ui/consts/static-mut-refs.rs
new file mode 100644
index 00000000000..ff865da5aa8
--- /dev/null
+++ b/tests/ui/consts/static-mut-refs.rs
@@ -0,0 +1,24 @@
+// run-pass
+#![allow(dead_code)]
+
+// Checks that mutable static items can have mutable slices and other references
+
+
+static mut TEST: &'static mut [isize] = &mut [1];
+static mut EMPTY: &'static mut [isize] = &mut [];
+static mut INT: &'static mut isize = &mut 1;
+
+// And the same for raw pointers.
+
+static mut TEST_RAW: *mut [isize] = &mut [1isize] as *mut _;
+static mut EMPTY_RAW: *mut [isize] = &mut [] as *mut _;
+static mut INT_RAW: *mut isize = &mut 1isize as *mut _;
+
+pub fn main() {
+    unsafe {
+        TEST[0] += 1;
+        assert_eq!(TEST[0], 2);
+        *INT_RAW += 1;
+        assert_eq!(*INT_RAW, 2);
+    }
+}
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.rs b/tests/ui/consts/static_mut_containing_mut_ref2.rs
index fa79a78eab4..b71f1122cd0 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.rs
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.rs
@@ -7,7 +7,7 @@ static mut STDERR_BUFFER_SPACE: u8 = 0;
 pub static mut STDERR_BUFFER: () = unsafe {
     *(&mut STDERR_BUFFER_SPACE) = 42;
     //[mut_refs]~^ ERROR could not evaluate static initializer
-    //[stock]~^^ ERROR mutable references are not allowed in statics
+    //[stock]~^^ ERROR mutation through a reference is not allowed in statics
     //[mut_refs]~^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
     //[stock]~^^^^ WARN mutable reference of mutable static is discouraged [static_mut_ref]
 };
diff --git a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
index e9fe82d2f87..aea5b8a33b5 100644
--- a/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
+++ b/tests/ui/consts/static_mut_containing_mut_ref2.stock.stderr
@@ -13,11 +13,11 @@ help: mutable references are dangerous since if there's any other pointer or ref
 LL |     *addr_of_mut!(STDERR_BUFFER_SPACE) = 42;
    |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-error[E0658]: mutable references are not allowed in statics
-  --> $DIR/static_mut_containing_mut_ref2.rs:8:6
+error[E0658]: mutation through a reference is not allowed in statics
+  --> $DIR/static_mut_containing_mut_ref2.rs:8:5
    |
 LL |     *(&mut STDERR_BUFFER_SPACE) = 42;
-   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
index f87d3aab635..717da41f871 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
@@ -42,31 +42,20 @@ type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
 
 fn _apit(_: impl Tr1<As1: Copy>) {}
 //~^ ERROR associated type bounds are unstable
-fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
-//~^ ERROR associated type bounds are unstable
 
 fn _rpit() -> impl Tr1<As1: Copy> { S1 }
 //~^ ERROR associated type bounds are unstable
 
-fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
-//~^ ERROR associated type bounds are unstable
-
 const _cdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
 //~| ERROR `impl Trait` is not allowed in const types
-// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
-// const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 static _sdef: impl Tr1<As1: Copy> = S1;
 //~^ ERROR associated type bounds are unstable
 //~| ERROR `impl Trait` is not allowed in static types
-// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
-// static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;
 
 fn main() {
     let _: impl Tr1<As1: Copy> = S1;
     //~^ ERROR associated type bounds are unstable
     //~| ERROR `impl Trait` is not allowed in the type of variable bindings
-    // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
-    // let _: &dyn Tr1<As1: Copy> = &S1;
 }
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
index 855a29953f1..1838eab5cda 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
@@ -69,17 +69,7 @@ LL | fn _apit(_: impl Tr1<As1: Copy>) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:45:26
-   |
-LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
-   |                          ^^^^^^^^^
-   |
-   = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
-   = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:48:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:46:24
    |
 LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    |                        ^^^^^^^^^
@@ -89,17 +79,7 @@ LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:51:31
-   |
-LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
-   |                               ^^^^^^^^^
-   |
-   = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
-   = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:54:23
+  --> $DIR/feature-gate-associated_type_bounds.rs:49:23
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |                       ^^^^^^^^^
@@ -109,7 +89,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:60:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:53:24
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |                        ^^^^^^^^^
@@ -119,7 +99,7 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:67:21
+  --> $DIR/feature-gate-associated_type_bounds.rs:58:21
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |                     ^^^^^^^^^
@@ -129,7 +109,7 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0562]: `impl Trait` is not allowed in const types
-  --> $DIR/feature-gate-associated_type_bounds.rs:54:14
+  --> $DIR/feature-gate-associated_type_bounds.rs:49:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
@@ -137,7 +117,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in static types
-  --> $DIR/feature-gate-associated_type_bounds.rs:60:15
+  --> $DIR/feature-gate-associated_type_bounds.rs:53:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
@@ -145,14 +125,14 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/feature-gate-associated_type_bounds.rs:67:12
+  --> $DIR/feature-gate-associated_type_bounds.rs:58:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |            ^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error: aborting due to 16 previous errors
+error: aborting due to 14 previous errors
 
 Some errors have detailed explanations: E0562, E0658.
 For more information about an error, try `rustc --explain E0562`.
diff --git a/tests/ui/specialization/allow_internal_unstable.rs b/tests/ui/specialization/min_specialization/allow_internal_unstable.rs
similarity index 64%
rename from tests/ui/specialization/allow_internal_unstable.rs
rename to tests/ui/specialization/min_specialization/allow_internal_unstable.rs
index 317782b7b72..8f3677d9769 100644
--- a/tests/ui/specialization/allow_internal_unstable.rs
+++ b/tests/ui/specialization/min_specialization/allow_internal_unstable.rs
@@ -5,6 +5,9 @@
 #![allow(internal_features)]
 #![feature(allow_internal_unstable)]
 
+// aux-build:specialization-trait.rs
+extern crate specialization_trait;
+
 #[allow_internal_unstable(min_specialization)]
 macro_rules! test {
     () => {
@@ -12,7 +15,11 @@ macro_rules! test {
         trait Tr {}
         impl<U> Tr for T<U> {}
         impl Tr for T<u8> {}
-    }
+
+        impl<U> specialization_trait::SpecTrait for T<U> {
+            fn method(&self) {}
+        }
+    };
 }
 
 test! {}
diff --git a/tests/ui/typeck/issue-120856.rs b/tests/ui/typeck/issue-120856.rs
new file mode 100644
index 00000000000..e435a0f9d8e
--- /dev/null
+++ b/tests/ui/typeck/issue-120856.rs
@@ -0,0 +1,5 @@
+pub type Archived<T> = <m::Alias as n::Trait>::Archived;
+//~^ ERROR failed to resolve: use of undeclared crate or module `m`
+//~| ERROR failed to resolve: use of undeclared crate or module `n`
+
+fn main() {}
diff --git a/tests/ui/typeck/issue-120856.stderr b/tests/ui/typeck/issue-120856.stderr
new file mode 100644
index 00000000000..1fc8b200473
--- /dev/null
+++ b/tests/ui/typeck/issue-120856.stderr
@@ -0,0 +1,21 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `n`
+  --> $DIR/issue-120856.rs:1:37
+   |
+LL | pub type Archived<T> = <m::Alias as n::Trait>::Archived;
+   |                                     ^
+   |                                     |
+   |                                     use of undeclared crate or module `n`
+   |                                     help: a trait with a similar name exists: `Fn`
+
+error[E0433]: failed to resolve: use of undeclared crate or module `m`
+  --> $DIR/issue-120856.rs:1:25
+   |
+LL | pub type Archived<T> = <m::Alias as n::Trait>::Archived;
+   |                         ^
+   |                         |
+   |                         use of undeclared crate or module `m`
+   |                         help: a type parameter with a similar name exists: `T`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.