about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-28 04:18:19 +0000
committerbors <bors@rust-lang.org>2022-09-28 04:18:19 +0000
commit837bf370de144a682041e68bb67469b9f68a55ce (patch)
treead6fb53f2919d4c12d206c01acf057104ff212aa
parentd6734be398fde0b078cde298e0d84eeccd71d08e (diff)
parentce15514df969522d507c6ab63f7472dc2c45d86c (diff)
downloadrust-837bf370de144a682041e68bb67469b9f68a55ce.tar.gz
rust-837bf370de144a682041e68bb67469b9f68a55ce.zip
Auto merge of #102388 - JohnTitor:rollup-mbyw6fl, r=JohnTitor
Rollup of 8 pull requests

Successful merges:

 - #100747 (Add long description and test for E0311)
 - #102232 (Stabilize bench_black_box)
 - #102288 (Suggest unwrapping `???<T>` if a method cannot be found on it but is present on `T`.)
 - #102338 (Deny associated type bindings within associated type bindings)
 - #102347 (Unescaping cleanups)
 - #102348 (Tweak `FulfillProcessor`.)
 - #102378 (Use already resolved `self_ty` in `confirm_fn_pointer_candidate`)
 - #102380 (rustdoc: remove redundant mobile `.source > .sidebar` CSS)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_cranelift/example/std_example.rs2
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/int.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0311.md42
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/check/method/suggest.rs210
-rw-r--r--compiler/rustc_index/src/lib.rs1
-rw-r--r--compiler/rustc_lexer/src/unescape.rs27
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs3
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/core/src/cell.rs1
-rw-r--r--library/core/src/hint.rs2
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/sync/rwlock.rs1
-rw-r--r--library/std/src/thread/local.rs1
-rw-r--r--library/test/src/lib.rs1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css3
-rw-r--r--src/test/incremental/spans_significant_w_panic.rs1
-rw-r--r--src/test/ui/associated-consts/issue-102335-const.rs12
-rw-r--r--src/test/ui/associated-consts/issue-102335-const.stderr9
-rw-r--r--src/test/ui/associated-type-bounds/issue-102335-ty.rs12
-rw-r--r--src/test/ui/associated-type-bounds/issue-102335-ty.stderr9
-rw-r--r--src/test/ui/box/issue-95036.rs2
-rw-r--r--src/test/ui/consts/cast-discriminant-zst-enum.rs1
-rw-r--r--src/test/ui/consts/const_discriminant.rs1
-rw-r--r--src/test/ui/error-codes/E0311.rs9
-rw-r--r--src/test/ui/error-codes/E0311.stderr24
-rw-r--r--src/test/ui/function-pointer/issue-102289.rs54
-rw-r--r--src/test/ui/generic-associated-types/issue-102335-gat.rs12
-rw-r--r--src/test/ui/generic-associated-types/issue-102335-gat.stderr9
-rw-r--r--src/test/ui/issues/issue-99838.rs2
-rw-r--r--src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr1
-rw-r--r--src/test/ui/oom_unwind.rs2
-rw-r--r--src/test/ui/process/process-panic-after-fork.rs1
-rw-r--r--src/test/ui/sanitize/address.rs4
-rw-r--r--src/test/ui/sanitize/hwaddress.rs2
-rw-r--r--src/test/ui/sanitize/leak.rs2
-rw-r--r--src/test/ui/sanitize/memory-eager.rs1
-rw-r--r--src/test/ui/sanitize/memory.rs1
-rw-r--r--src/test/ui/suggestions/inner_type.fixed40
-rw-r--r--src/test/ui/suggestions/inner_type.rs40
-rw-r--r--src/test/ui/suggestions/inner_type.stderr83
-rw-r--r--src/test/ui/suggestions/inner_type2.rs26
-rw-r--r--src/test/ui/suggestions/inner_type2.stderr29
-rw-r--r--src/test/ui/suggestions/issue-85347.rs1
-rw-r--r--src/test/ui/suggestions/issue-85347.stderr11
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr1
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr2
-rw-r--r--src/tools/miri/tests/fail/invalid_bool.rs2
-rw-r--r--src/tools/miri/tests/pass/float.rs2
-rw-r--r--src/tools/miri/tests/pass/u128.rs1
54 files changed, 622 insertions, 127 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs
index 0b5b6cd55d7..ad108c34992 100644
--- a/compiler/rustc_codegen_cranelift/example/std_example.rs
+++ b/compiler/rustc_codegen_cranelift/example/std_example.rs
@@ -1,4 +1,4 @@
-#![feature(core_intrinsics, generators, generator_trait, is_sorted, bench_black_box)]
+#![feature(core_intrinsics, generators, generator_trait, is_sorted)]
 
 #[cfg(target_arch = "x86_64")]
 use std::arch::x86_64::*;
diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs
index 2b90e4ae8d8..75779622b54 100644
--- a/compiler/rustc_codegen_gcc/tests/run/int.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/int.rs
@@ -3,7 +3,7 @@
 // Run-time:
 //   status: 0
 
-#![feature(bench_black_box, const_black_box, core_intrinsics, start)]
+#![feature(const_black_box, core_intrinsics, start)]
 
 #![no_std]
 
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 854625579ee..1e86d159668 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -159,6 +159,7 @@ E0307: include_str!("./error_codes/E0307.md"),
 E0308: include_str!("./error_codes/E0308.md"),
 E0309: include_str!("./error_codes/E0309.md"),
 E0310: include_str!("./error_codes/E0310.md"),
+E0311: include_str!("./error_codes/E0311.md"),
 E0312: include_str!("./error_codes/E0312.md"),
 E0316: include_str!("./error_codes/E0316.md"),
 E0317: include_str!("./error_codes/E0317.md"),
@@ -568,7 +569,6 @@ E0790: include_str!("./error_codes/E0790.md"),
 //  E0300, // unexpanded macro
 //  E0304, // expected signed integer constant
 //  E0305, // expected constant
-    E0311, // thing may not live long enough
     E0313, // lifetime of borrowed pointer outlives lifetime of captured
            // variable
 //  E0314, // closure outlives stack frame
diff --git a/compiler/rustc_error_codes/src/error_codes/E0311.md b/compiler/rustc_error_codes/src/error_codes/E0311.md
new file mode 100644
index 00000000000..08159d3f469
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0311.md
@@ -0,0 +1,42 @@
+This error occurs when there is an unsatisfied outlives bound involving an
+elided region and a generic type parameter or associated type.
+
+Erroneous code example:
+
+```compile_fail,E0311
+fn no_restriction<T>(x: &()) -> &() {
+    with_restriction::<T>(x)
+}
+
+fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    x
+}
+```
+
+Why doesn't this code compile? It helps to look at the lifetime bounds that are
+automatically added by the compiler. For more details see the documentation for
+[lifetime elision]( https://doc.rust-lang.org/reference/lifetime-elision.html).
+
+The compiler elides the lifetime of `x` and the return type to some arbitrary
+lifetime `'anon` in `no_restriction()`. The only information available to the
+compiler is that `'anon` is valid for the duration of the function. When
+calling `with_restriction()`, the compiler requires the completely unrelated
+type parameter `T` to outlive `'anon` because of the `T: 'a` bound in
+`with_restriction()`. This causes an error because `T` is not required to
+outlive `'anon` in `no_restriction()`.
+
+If `no_restriction()` were to use `&T` instead of `&()` as an argument, the
+compiler would have added an implied bound, causing this to compile.
+
+This error can be resolved by explicitly naming the elided lifetime for `x` and
+then explicily requiring that the generic parameter `T` outlives that lifetime:
+
+```
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    with_restriction::<T>(x)
+}
+
+fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    x
+}
+```
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index b3cbb606c72..244018ebbeb 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -595,7 +595,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             "create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
             span, item_def_id, item_segment
         );
-        self.create_substs_for_ast_path(
+        let (args, _) = self.create_substs_for_ast_path(
             span,
             item_def_id,
             parent_substs,
@@ -603,8 +603,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             item_segment.args(),
             item_segment.infer_args,
             None,
-        )
-        .0
+        );
+
+        let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
+        if let Some(b) = assoc_bindings.first() {
+            Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
+        }
+
+        args
     }
 
     /// Instantiates the path for the given trait reference, assuming that it's
diff --git a/compiler/rustc_hir_analysis/src/check/method/suggest.rs b/compiler/rustc_hir_analysis/src/check/method/suggest.rs
index 0e77ed0a4fe..0e82e4956c7 100644
--- a/compiler/rustc_hir_analysis/src/check/method/suggest.rs
+++ b/compiler/rustc_hir_analysis/src/check/method/suggest.rs
@@ -2,6 +2,7 @@
 //! found or is otherwise invalid.
 
 use crate::check::FnCtxt;
+use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{
     pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
@@ -30,7 +31,7 @@ use rustc_trait_selection::traits::{
 use std::cmp::Ordering;
 use std::iter;
 
-use super::probe::{IsSuggestion, Mode, ProbeScope};
+use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope};
 use super::{CandidateSource, MethodError, NoMatchData};
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -983,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.check_for_field_method(&mut err, source, span, actual, item_name);
                 }
 
-                self.check_for_unwrap_self(&mut err, source, span, actual, item_name);
+                self.check_for_inner_self(&mut err, source, span, actual, item_name);
 
                 bound_spans.sort();
                 bound_spans.dedup();
@@ -1395,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_for_unwrap_self(
+    fn check_for_inner_self(
         &self,
         err: &mut Diagnostic,
         source: SelfSource<'tcx>,
@@ -1408,81 +1409,168 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
 
         let ty::Adt(kind, substs) = actual.kind() else { return; };
-        if !kind.is_enum() {
-            return;
-        }
+        match kind.adt_kind() {
+            ty::AdtKind::Enum => {
+                let matching_variants: Vec<_> = kind
+                    .variants()
+                    .iter()
+                    .flat_map(|variant| {
+                        let [field] = &variant.fields[..] else { return None; };
+                        let field_ty = field.ty(tcx, substs);
+
+                        // Skip `_`, since that'll just lead to ambiguity.
+                        if self.resolve_vars_if_possible(field_ty).is_ty_var() {
+                            return None;
+                        }
 
-        let matching_variants: Vec<_> = kind
-            .variants()
-            .iter()
-            .flat_map(|variant| {
-                let [field] = &variant.fields[..] else { return None; };
-                let field_ty = field.ty(tcx, substs);
+                        self.lookup_probe(
+                            span,
+                            item_name,
+                            field_ty,
+                            call_expr,
+                            ProbeScope::TraitsInScope,
+                        )
+                        .ok()
+                        .map(|pick| (variant, field, pick))
+                    })
+                    .collect();
+
+                let ret_ty_matches = |diagnostic_item| {
+                    if let Some(ret_ty) = self
+                        .ret_coercion
+                        .as_ref()
+                        .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
+                        && let ty::Adt(kind, _) = ret_ty.kind()
+                        && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
+                    {
+                        true
+                    } else {
+                        false
+                    }
+                };
 
-                // Skip `_`, since that'll just lead to ambiguity.
-                if self.resolve_vars_if_possible(field_ty).is_ty_var() {
-                    return None;
+                match &matching_variants[..] {
+                    [(_, field, pick)] => {
+                        let self_ty = field.ty(tcx, substs);
+                        err.span_note(
+                            tcx.def_span(pick.item.def_id),
+                            &format!("the method `{item_name}` exists on the type `{self_ty}`"),
+                        );
+                        let (article, kind, variant, question) =
+                            if tcx.is_diagnostic_item(sym::Result, kind.did()) {
+                                ("a", "Result", "Err", ret_ty_matches(sym::Result))
+                            } else if tcx.is_diagnostic_item(sym::Option, kind.did()) {
+                                ("an", "Option", "None", ret_ty_matches(sym::Option))
+                            } else {
+                                return;
+                            };
+                        if question {
+                            err.span_suggestion_verbose(
+                                expr.span.shrink_to_hi(),
+                                format!(
+                                    "use the `?` operator to extract the `{self_ty}` value, propagating \
+                                    {article} `{kind}::{variant}` value to the caller"
+                                ),
+                                "?",
+                                Applicability::MachineApplicable,
+                            );
+                        } else {
+                            err.span_suggestion_verbose(
+                                expr.span.shrink_to_hi(),
+                                format!(
+                                    "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
+                                    panicking if the value is {article} `{kind}::{variant}`"
+                                ),
+                                ".expect(\"REASON\")",
+                                Applicability::HasPlaceholders,
+                            );
+                        }
+                    }
+                    // FIXME(compiler-errors): Support suggestions for other matching enum variants
+                    _ => {}
                 }
-
-                self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
-                    .ok()
-                    .map(|pick| (variant, field, pick))
-            })
-            .collect();
-
-        let ret_ty_matches = |diagnostic_item| {
-            if let Some(ret_ty) = self
-                .ret_coercion
-                .as_ref()
-                .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
-                && let ty::Adt(kind, _) = ret_ty.kind()
-                && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
-            {
-                true
-            } else {
-                false
             }
-        };
+            // Target wrapper types - types that wrap or pretend to wrap another type,
+            // perhaps this inner type is meant to be called?
+            ty::AdtKind::Struct | ty::AdtKind::Union => {
+                let [first] = ***substs else { return; };
+                let ty::GenericArgKind::Type(ty) = first.unpack() else { return; };
+                let Ok(pick) = self.lookup_probe(
+                            span,
+                            item_name,
+                            ty,
+                            call_expr,
+                            ProbeScope::TraitsInScope,
+                        )  else { return; };
 
-        match &matching_variants[..] {
-            [(_, field, pick)] => {
-                let self_ty = field.ty(tcx, substs);
-                err.span_note(
-                    tcx.def_span(pick.item.def_id),
-                    &format!("the method `{item_name}` exists on the type `{self_ty}`"),
-                );
-                let (article, kind, variant, question) =
-                    if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) {
-                        ("a", "Result", "Err", ret_ty_matches(sym::Result))
-                    } else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) {
-                        ("an", "Option", "None", ret_ty_matches(sym::Option))
-                    } else {
-                        return;
+                let name = self.ty_to_value_string(actual);
+                let inner_id = kind.did();
+                let mutable = if let Some(AutorefOrPtrAdjustment::Autoref { mutbl, .. }) =
+                    pick.autoref_or_ptr_adjustment
+                {
+                    Some(mutbl)
+                } else {
+                    None
+                };
+
+                if tcx.is_diagnostic_item(sym::LocalKey, inner_id) {
+                    err.help("use `with` or `try_with` to access thread local storage");
+                } else if Some(kind.did()) == tcx.lang_items().maybe_uninit() {
+                    err.help(format!(
+                        "if this `{name}` has been initialized, \
+                        use one of the `assume_init` methods to access the inner value"
+                    ));
+                } else if tcx.is_diagnostic_item(sym::RefCell, inner_id) {
+                    let (suggestion, borrow_kind, panic_if) = match mutable {
+                        Some(Mutability::Not) => (".borrow()", "borrow", "a mutable borrow exists"),
+                        Some(Mutability::Mut) => {
+                            (".borrow_mut()", "mutably borrow", "any borrows exist")
+                        }
+                        None => return,
                     };
-                if question {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_hi(),
                         format!(
-                            "use the `?` operator to extract the `{self_ty}` value, propagating \
-                            {article} `{kind}::{variant}` value to the caller"
+                            "use `{suggestion}` to {borrow_kind} the `{ty}`, \
+                            panicking if {panic_if}"
                         ),
-                        "?",
-                        Applicability::MachineApplicable,
+                        suggestion,
+                        Applicability::MaybeIncorrect,
                     );
-                } else {
+                } else if tcx.is_diagnostic_item(sym::Mutex, inner_id) {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_hi(),
                         format!(
-                            "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
-                             panicking if the value is {article} `{kind}::{variant}`"
+                            "use `.lock().unwrap()` to borrow the `{ty}`, \
+                            blocking the current thread until it can be acquired"
                         ),
-                        ".expect(\"REASON\")",
-                        Applicability::HasPlaceholders,
+                        ".lock().unwrap()",
+                        Applicability::MaybeIncorrect,
                     );
-                }
+                } else if tcx.is_diagnostic_item(sym::RwLock, inner_id) {
+                    let (suggestion, borrow_kind) = match mutable {
+                        Some(Mutability::Not) => (".read().unwrap()", "borrow"),
+                        Some(Mutability::Mut) => (".write().unwrap()", "mutably borrow"),
+                        None => return,
+                    };
+                    err.span_suggestion_verbose(
+                        expr.span.shrink_to_hi(),
+                        format!(
+                            "use `{suggestion}` to {borrow_kind} the `{ty}`, \
+                            blocking the current thread until it can be acquired"
+                        ),
+                        suggestion,
+                        Applicability::MaybeIncorrect,
+                    );
+                } else {
+                    return;
+                };
+
+                err.span_note(
+                    tcx.def_span(pick.item.def_id),
+                    &format!("the method `{item_name}` exists on the type `{ty}`"),
+                );
             }
-            // FIXME(compiler-errors): Support suggestions for other matching enum variants
-            _ => {}
         }
     }
 
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 9753fb35530..23a4c1f0696 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -1,7 +1,6 @@
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(allow_internal_unstable)]
-#![feature(bench_black_box)]
 #![feature(extend_one)]
 #![feature(min_specialization)]
 #![feature(new_uninit)]
diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index 3da6bc14622..8f64b5f5158 100644
--- a/compiler/rustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
@@ -93,7 +93,7 @@ where
         // NOTE: Raw strings do not perform any explicit character escaping, here we
         // only translate CRLF to LF and produce errors on bare CR.
         Mode::RawStr | Mode::RawByteStr => {
-            unescape_raw_str_or_byte_str(literal_text, mode, callback)
+            unescape_raw_str_or_raw_byte_str(literal_text, mode, callback)
         }
     }
 }
@@ -105,7 +105,7 @@ pub fn unescape_byte_literal<F>(literal_text: &str, mode: Mode, callback: &mut F
 where
     F: FnMut(Range<usize>, Result<u8, EscapeError>),
 {
-    assert!(mode.is_bytes());
+    debug_assert!(mode.is_bytes());
     unescape_literal(literal_text, mode, &mut |range, result| {
         callback(range, result.map(byte_from_char));
     })
@@ -129,7 +129,7 @@ pub fn unescape_byte(literal_text: &str) -> Result<u8, (usize, EscapeError)> {
 }
 
 /// What kind of literal do we parse.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq)]
 pub enum Mode {
     Char,
     Str,
@@ -140,17 +140,13 @@ pub enum Mode {
 }
 
 impl Mode {
-    pub fn in_single_quotes(self) -> bool {
+    pub fn in_double_quotes(self) -> bool {
         match self {
-            Mode::Char | Mode::Byte => true,
-            Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => false,
+            Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => true,
+            Mode::Char | Mode::Byte => false,
         }
     }
 
-    pub fn in_double_quotes(self) -> bool {
-        !self.in_single_quotes()
-    }
-
     pub fn is_bytes(self) -> bool {
         match self {
             Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true,
@@ -184,7 +180,7 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result<char, EscapeError> {
 
             let value = hi * 16 + lo;
 
-            // For a byte literal verify that it is within ASCII range.
+            // For a non-byte literal verify that it is within ASCII range.
             if !mode.is_bytes() && !is_ascii(value) {
                 return Err(EscapeError::OutOfRangeHexEscape);
             }
@@ -263,6 +259,7 @@ fn ascii_check(first_char: char, mode: Mode) -> Result<char, EscapeError> {
 }
 
 fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result<char, EscapeError> {
+    debug_assert!(mode == Mode::Char || mode == Mode::Byte);
     let first_char = chars.next().ok_or(EscapeError::ZeroChars)?;
     let res = match first_char {
         '\\' => scan_escape(chars, mode),
@@ -282,7 +279,7 @@ fn unescape_str_or_byte_str<F>(src: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<char, EscapeError>),
 {
-    assert!(mode.in_double_quotes());
+    debug_assert!(mode == Mode::Str || mode == Mode::ByteStr);
     let initial_len = src.len();
     let mut chars = src.chars();
     while let Some(first_char) = chars.next() {
@@ -344,11 +341,11 @@ where
 /// sequence of characters or errors.
 /// NOTE: Raw strings do not perform any explicit character escaping, here we
 /// only translate CRLF to LF and produce errors on bare CR.
-fn unescape_raw_str_or_byte_str<F>(literal_text: &str, mode: Mode, callback: &mut F)
+fn unescape_raw_str_or_raw_byte_str<F>(literal_text: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<char, EscapeError>),
 {
-    assert!(mode.in_double_quotes());
+    debug_assert!(mode == Mode::RawStr || mode == Mode::RawByteStr);
     let initial_len = literal_text.len();
 
     let mut chars = literal_text.chars();
@@ -368,7 +365,7 @@ where
 
 fn byte_from_char(c: char) -> u8 {
     let res = c as u32;
-    assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr");
+    debug_assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr");
     res as u8
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7657f9486c2..07f3656d086 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -224,6 +224,7 @@ symbols! {
         Left,
         LinkedList,
         LintPass,
+        LocalKey,
         Mutex,
         MutexGuard,
         N,
@@ -266,6 +267,7 @@ symbols! {
         Rc,
         Ready,
         Receiver,
+        RefCell,
         Relaxed,
         Release,
         Result,
@@ -274,6 +276,7 @@ symbols! {
         Rust,
         RustcDecodable,
         RustcEncodable,
+        RwLock,
         RwLockReadGuard,
         RwLockWriteGuard,
         Send,
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 6f3a9412dde..f13736a76b2 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -102,7 +102,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
     }
 
     /// Attempts to select obligations using `selcx`.
-    fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
+    fn select(&mut self, selcx: SelectionContext<'a, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
         let span = debug_span!("select", obligation_forest_size = ?self.predicates.len());
         let _enter = span.enter();
 
@@ -197,8 +197,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         &mut self,
         infcx: &InferCtxt<'_, 'tcx>,
     ) -> Vec<FulfillmentError<'tcx>> {
-        let mut selcx = SelectionContext::new(infcx);
-        self.select(&mut selcx)
+        let selcx = SelectionContext::new(infcx);
+        self.select(selcx)
     }
 
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
@@ -210,8 +210,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     }
 }
 
-struct FulfillProcessor<'a, 'b, 'tcx> {
-    selcx: &'a mut SelectionContext<'b, 'tcx>,
+struct FulfillProcessor<'a, 'tcx> {
+    selcx: SelectionContext<'a, 'tcx>,
 }
 
 fn mk_pending(os: Vec<PredicateObligation<'_>>) -> Vec<PendingPredicateObligation<'_>> {
@@ -220,7 +220,7 @@ fn mk_pending(os: Vec<PredicateObligation<'_>>) -> Vec<PendingPredicateObligatio
         .collect()
 }
 
-impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
+impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
     type Obligation = PendingPredicateObligation<'tcx>;
     type Error = FulfillmentErrorCode<'tcx>;
     type OUT = Outcome<Self::Obligation, Self::Error>;
@@ -291,7 +291,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
         if obligation.predicate.has_projections() {
             let mut obligations = Vec::new();
             let predicate = crate::traits::project::try_normalize_with_depth_to(
-                self.selcx,
+                &mut self.selcx,
                 obligation.param_env,
                 obligation.cause.clone(),
                 obligation.recursion_depth + 1,
@@ -608,7 +608,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
+impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
     #[instrument(level = "debug", skip(self, obligation, stalled_on))]
     fn process_trait_obligation(
         &mut self,
@@ -643,7 +643,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
                 // information about the types in the trait.
                 stalled_on.clear();
                 stalled_on.extend(substs_infer_vars(
-                    self.selcx,
+                    &self.selcx,
                     trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs),
                 ));
 
@@ -695,12 +695,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
             }
         }
 
-        match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
+        match project::poly_project_and_unify_type(&mut self.selcx, &project_obligation) {
             ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
             ProjectAndUnifyResult::FailedNormalization => {
                 stalled_on.clear();
                 stalled_on.extend(substs_infer_vars(
-                    self.selcx,
+                    &self.selcx,
                     project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs),
                 ));
                 ProcessResult::Unchanged
@@ -718,7 +718,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
 
 /// Returns the set of inference variables contained in `substs`.
 fn substs_infer_vars<'a, 'tcx>(
-    selcx: &mut SelectionContext<'a, 'tcx>,
+    selcx: &SelectionContext<'a, 'tcx>,
     substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
 ) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
     selcx
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 27fbfb6dd21..dd49dcecf77 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -626,7 +626,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // the signature, as evidenced by how we treat it during projection.
         // The safe thing to do here is to liberate it, though, which should
         // have no worse effect than skipping the binder here.
-        let liberated_fn_ty = self.infcx.replace_bound_vars_with_placeholders(obligation.self_ty());
+        let liberated_fn_ty =
+            self.infcx.replace_bound_vars_with_placeholders(obligation.predicate.rebind(self_ty));
         let output_ty = self
             .infcx
             .replace_bound_vars_with_placeholders(liberated_fn_ty.fn_sig(self.tcx()).output());
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 55aced5106c..f30ebd77e24 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -41,7 +41,6 @@
 #![feature(pointer_is_aligned)]
 #![feature(slice_flatten)]
 #![feature(thin_box)]
-#![feature(bench_black_box)]
 #![feature(strict_provenance)]
 #![feature(once_cell)]
 #![feature(drain_keep_rest)]
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 1abbb39497a..288cab1ef39 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -614,6 +614,7 @@ impl<T, const N: usize> Cell<[T; N]> {
 /// A mutable memory location with dynamically checked borrow rules
 ///
 /// See the [module-level documentation](self) for more.
+#[cfg_attr(not(test), rustc_diagnostic_item = "RefCell")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RefCell<T: ?Sized> {
     borrow: Cell<BorrowFlag>,
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 764e2796202..f9267371aa7 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -217,7 +217,7 @@ pub fn spin_loop() {
 ///
 /// [`std::convert::identity`]: crate::convert::identity
 #[inline]
-#[unstable(feature = "bench_black_box", issue = "64102")]
+#[stable(feature = "bench_black_box", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
 pub const fn black_box<T>(dummy: T) -> T {
     crate::intrinsics::black_box(dummy)
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 46f603eaeba..6d58ed9743d 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -2,7 +2,6 @@
 #![feature(array_chunks)]
 #![feature(array_methods)]
 #![feature(array_windows)]
-#![feature(bench_black_box)]
 #![feature(bigint_helper_methods)]
 #![feature(cell_update)]
 #![feature(const_assume)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index ac5d0384d43..64b62fd3bba 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -348,7 +348,6 @@
 #![feature(trace_macros)]
 //
 // Only used in tests/benchmarks:
-#![feature(bench_black_box)]
 //
 // Only for const-ness:
 #![feature(const_io_structs)]
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9ab781561e9..ee2c79b6669 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -76,6 +76,7 @@ use crate::sys_common::rwlock as sys;
 ///
 /// [`Mutex`]: super::Mutex
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")]
 pub struct RwLock<T: ?Sized> {
     inner: sys::MovableRwLock,
     poison: poison::Flag,
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 8aedfc4a6b8..ffd17dc9909 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -95,6 +95,7 @@ use crate::fmt;
 /// [loader lock]: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
 /// [`JoinHandle::join`]: crate::thread::JoinHandle::join
 /// [`with`]: LocalKey::with
+#[cfg_attr(not(test), rustc_diagnostic_item = "LocalKey")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct LocalKey<T: 'static> {
     // This outer `LocalKey<T>` type is what's going to be stored in statics,
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 3b7193adcc7..33c6ea58532 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -15,7 +15,6 @@
 
 #![unstable(feature = "test", issue = "50297")]
 #![doc(test(attr(deny(warnings))))]
-#![feature(bench_black_box)]
 #![feature(internal_output_capture)]
 #![feature(staged_api)]
 #![feature(process_exitcode_internals)]
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index c8ea5bef37a..0ea6d9c38b6 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1776,9 +1776,6 @@ in storage.js plus the media query with (min-width: 701px)
 	}
 
 	.rustdoc.source > .sidebar {
-		position: fixed;
-		margin: 0;
-		z-index: 11;
 		width: 0;
 	}
 
diff --git a/src/test/incremental/spans_significant_w_panic.rs b/src/test/incremental/spans_significant_w_panic.rs
index e9e35791aa1..6f51c9729e3 100644
--- a/src/test/incremental/spans_significant_w_panic.rs
+++ b/src/test/incremental/spans_significant_w_panic.rs
@@ -8,7 +8,6 @@
 // compile-flags: -C overflow-checks=on -Z query-dep-graph
 
 #![feature(rustc_attrs)]
-#![feature(bench_black_box)]
 #![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass2")]
 #![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass4")]
 
diff --git a/src/test/ui/associated-consts/issue-102335-const.rs b/src/test/ui/associated-consts/issue-102335-const.rs
new file mode 100644
index 00000000000..f60cb92da7f
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-102335-const.rs
@@ -0,0 +1,12 @@
+#![feature(associated_const_equality)]
+
+trait T {
+    type A: S<C<X = 0i32> = 34>;
+    //~^ ERROR associated type bindings are not allowed here
+}
+
+trait S {
+    const C: i32;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-consts/issue-102335-const.stderr b/src/test/ui/associated-consts/issue-102335-const.stderr
new file mode 100644
index 00000000000..531d15c5900
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-102335-const.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-102335-const.rs:4:17
+   |
+LL |     type A: S<C<X = 0i32> = 34>;
+   |                 ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.rs b/src/test/ui/associated-type-bounds/issue-102335-ty.rs
new file mode 100644
index 00000000000..363df73c1ff
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/issue-102335-ty.rs
@@ -0,0 +1,12 @@
+trait T {
+    type A: S<C<i32 = u32> = ()>;
+    //~^ ERROR associated type bindings are not allowed here
+}
+
+trait Q {}
+
+trait S {
+    type C: Q;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.stderr b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr
new file mode 100644
index 00000000000..8777b296515
--- /dev/null
+++ b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-102335-ty.rs:2:17
+   |
+LL |     type A: S<C<i32 = u32> = ()>;
+   |                 ^^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/box/issue-95036.rs b/src/test/ui/box/issue-95036.rs
index c2d4275aa49..0611fabc15c 100644
--- a/src/test/ui/box/issue-95036.rs
+++ b/src/test/ui/box/issue-95036.rs
@@ -1,7 +1,7 @@
 // compile-flags: -O
 // build-pass
 
-#![feature(allocator_api, bench_black_box)]
+#![feature(allocator_api)]
 
 #[inline(never)]
 pub fn by_ref(node: &mut Box<[u8; 1], &std::alloc::Global>) {
diff --git a/src/test/ui/consts/cast-discriminant-zst-enum.rs b/src/test/ui/consts/cast-discriminant-zst-enum.rs
index e59ae297da1..2767f178fb6 100644
--- a/src/test/ui/consts/cast-discriminant-zst-enum.rs
+++ b/src/test/ui/consts/cast-discriminant-zst-enum.rs
@@ -1,6 +1,5 @@
 // run-pass
 // Test a ZST enum whose dicriminant is ~0i128. This caused an ICE when casting to an i32.
-#![feature(bench_black_box)]
 use std::hint::black_box;
 
 #[derive(Copy, Clone)]
diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs
index f623c5101f4..79e68590e85 100644
--- a/src/test/ui/consts/const_discriminant.rs
+++ b/src/test/ui/consts/const_discriminant.rs
@@ -1,6 +1,5 @@
 // run-pass
 #![feature(const_discriminant)]
-#![feature(bench_black_box)]
 #![allow(dead_code)]
 
 use std::mem::{discriminant, Discriminant};
diff --git a/src/test/ui/error-codes/E0311.rs b/src/test/ui/error-codes/E0311.rs
new file mode 100644
index 00000000000..566b518b433
--- /dev/null
+++ b/src/test/ui/error-codes/E0311.rs
@@ -0,0 +1,9 @@
+fn no_restriction<T>(x: &()) -> &() {
+    with_restriction::<T>(x) //~ ERROR E0311
+}
+
+fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0311.stderr b/src/test/ui/error-codes/E0311.stderr
new file mode 100644
index 00000000000..9873b5ae6ff
--- /dev/null
+++ b/src/test/ui/error-codes/E0311.stderr
@@ -0,0 +1,24 @@
+error[E0311]: the parameter type `T` may not live long enough
+  --> $DIR/E0311.rs:2:5
+   |
+LL |     with_restriction::<T>(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+  --> $DIR/E0311.rs:1:25
+   |
+LL | fn no_restriction<T>(x: &()) -> &() {
+   |                         ^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+  --> $DIR/E0311.rs:2:5
+   |
+LL |     with_restriction::<T>(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
+   |                   +++  ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/function-pointer/issue-102289.rs b/src/test/ui/function-pointer/issue-102289.rs
new file mode 100644
index 00000000000..de394ca9ad6
--- /dev/null
+++ b/src/test/ui/function-pointer/issue-102289.rs
@@ -0,0 +1,54 @@
+// check-pass
+
+pub(crate) trait Parser: Sized {
+    type Output;
+    fn parse(&mut self, _input: &str) -> Result<(), ()> {
+        loop {}
+    }
+    fn map<F, B>(self, _f: F) -> Map<Self, F>
+    where
+        F: FnMut(Self::Output) -> B,
+    {
+        todo!()
+    }
+}
+
+pub(crate) struct Chainl1<P, Op>(P, Op);
+impl<P, Op> Parser for Chainl1<P, Op>
+where
+    P: Parser,
+    Op: Parser,
+    Op::Output: FnOnce(P::Output, P::Output) -> P::Output,
+{
+    type Output = P::Output;
+}
+pub(crate) fn chainl1<P, Op>(_parser: P, _op: Op) -> Chainl1<P, Op>
+where
+    P: Parser,
+    Op: Parser,
+    Op::Output: FnOnce(P::Output, P::Output) -> P::Output,
+{
+    loop {}
+}
+
+pub(crate) struct Map<P, F>(P, F);
+impl<A, B, P, F> Parser for Map<P, F>
+where
+    P: Parser<Output = A>,
+    F: FnMut(A) -> B,
+{
+    type Output = B;
+}
+
+impl Parser for u32 {
+    type Output = ();
+}
+
+pub fn chainl1_error_consume() {
+    fn first<T, U>(t: T, _: U) -> T {
+        t
+    }
+    let _ = chainl1(1, 1.map(|_| first)).parse("");
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.rs b/src/test/ui/generic-associated-types/issue-102335-gat.rs
new file mode 100644
index 00000000000..a7255fdcbf5
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102335-gat.rs
@@ -0,0 +1,12 @@
+trait T {
+    type A: S<C<(), i32 = ()> = ()>;
+    //~^ ERROR associated type bindings are not allowed here
+}
+
+trait Q {}
+
+trait S {
+    type C<T>: Q;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.stderr b/src/test/ui/generic-associated-types/issue-102335-gat.stderr
new file mode 100644
index 00000000000..7a7900a1e65
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-102335-gat.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-102335-gat.rs:2:21
+   |
+LL |     type A: S<C<(), i32 = ()> = ()>;
+   |                     ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/issues/issue-99838.rs b/src/test/ui/issues/issue-99838.rs
index eaeeac72b25..2e81d5e8221 100644
--- a/src/test/ui/issues/issue-99838.rs
+++ b/src/test/ui/issues/issue-99838.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![feature(bench_black_box)]
+
 use std::hint;
 
 struct U16(u16);
diff --git a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
index a8b0996d8b0..31fd8a4d633 100644
--- a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
+++ b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
@@ -21,3 +21,4 @@ LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/oom_unwind.rs b/src/test/ui/oom_unwind.rs
index d036c817a0e..21a8fb2b22b 100644
--- a/src/test/ui/oom_unwind.rs
+++ b/src/test/ui/oom_unwind.rs
@@ -4,8 +4,6 @@
 // needs-unwind
 // only-linux
 
-#![feature(bench_black_box)]
-
 use std::hint::black_box;
 use std::mem::forget;
 use std::panic::catch_unwind;
diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs
index 1ccf6bb051c..08b30b600e7 100644
--- a/src/test/ui/process/process-panic-after-fork.rs
+++ b/src/test/ui/process/process-panic-after-fork.rs
@@ -7,7 +7,6 @@
 // ignore-sgx no processes
 // ignore-android: FIXME(#85261)
 
-#![feature(bench_black_box)]
 #![feature(rustc_private)]
 #![feature(never_type)]
 #![feature(panic_always_abort)]
diff --git a/src/test/ui/sanitize/address.rs b/src/test/ui/sanitize/address.rs
index 9a26a351d99..5b2cea87560 100644
--- a/src/test/ui/sanitize/address.rs
+++ b/src/test/ui/sanitize/address.rs
@@ -5,9 +5,7 @@
 //
 // run-fail
 // error-pattern: AddressSanitizer: stack-buffer-overflow
-// error-pattern: 'xs' (line 15) <== Memory access at offset
-
-#![feature(bench_black_box)]
+// error-pattern: 'xs' (line 13) <== Memory access at offset
 
 use std::hint::black_box;
 
diff --git a/src/test/ui/sanitize/hwaddress.rs b/src/test/ui/sanitize/hwaddress.rs
index b988035f75e..f9b37a155aa 100644
--- a/src/test/ui/sanitize/hwaddress.rs
+++ b/src/test/ui/sanitize/hwaddress.rs
@@ -10,8 +10,6 @@
 // run-fail
 // error-pattern: HWAddressSanitizer: tag-mismatch
 
-#![feature(bench_black_box)]
-
 use std::hint::black_box;
 
 fn main() {
diff --git a/src/test/ui/sanitize/leak.rs b/src/test/ui/sanitize/leak.rs
index f63f81352da..cbb44ae8acd 100644
--- a/src/test/ui/sanitize/leak.rs
+++ b/src/test/ui/sanitize/leak.rs
@@ -6,8 +6,6 @@
 // run-fail
 // error-pattern: LeakSanitizer: detected memory leaks
 
-#![feature(bench_black_box)]
-
 use std::hint::black_box;
 use std::mem;
 
diff --git a/src/test/ui/sanitize/memory-eager.rs b/src/test/ui/sanitize/memory-eager.rs
index cc0593ec07d..0018c2f7581 100644
--- a/src/test/ui/sanitize/memory-eager.rs
+++ b/src/test/ui/sanitize/memory-eager.rs
@@ -17,7 +17,6 @@
 
 #![feature(core_intrinsics)]
 #![feature(start)]
-#![feature(bench_black_box)]
 
 use std::hint::black_box;
 use std::mem::MaybeUninit;
diff --git a/src/test/ui/sanitize/memory.rs b/src/test/ui/sanitize/memory.rs
index 14d4de65dd3..1a9ac3a4f3c 100644
--- a/src/test/ui/sanitize/memory.rs
+++ b/src/test/ui/sanitize/memory.rs
@@ -16,7 +16,6 @@
 
 #![feature(core_intrinsics)]
 #![feature(start)]
-#![feature(bench_black_box)]
 #![allow(invalid_value)]
 
 use std::hint::black_box;
diff --git a/src/test/ui/suggestions/inner_type.fixed b/src/test/ui/suggestions/inner_type.fixed
new file mode 100644
index 00000000000..7af7391ca85
--- /dev/null
+++ b/src/test/ui/suggestions/inner_type.fixed
@@ -0,0 +1,40 @@
+// compile-flags: --edition=2021
+// run-rustfix
+
+pub struct Struct<T> {
+    pub p: T,
+}
+
+impl<T> Struct<T> {
+    pub fn method(&self) {}
+
+    pub fn some_mutable_method(&mut self) {}
+}
+
+fn main() {
+    let other_item = std::cell::RefCell::new(Struct { p: 42_u32 });
+
+    other_item.borrow().method();
+    //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599]
+    //~| HELP use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
+
+    other_item.borrow_mut().some_mutable_method();
+    //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599]
+    //~| HELP .borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
+
+    let another_item = std::sync::Mutex::new(Struct { p: 42_u32 });
+
+    another_item.lock().unwrap().method();
+    //~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599]
+    //~| HELP use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+
+    let another_item = std::sync::RwLock::new(Struct { p: 42_u32 });
+
+    another_item.read().unwrap().method();
+    //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599]
+    //~| HELP  use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+
+    another_item.write().unwrap().some_mutable_method();
+    //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599]
+    //~| HELP use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+}
diff --git a/src/test/ui/suggestions/inner_type.rs b/src/test/ui/suggestions/inner_type.rs
new file mode 100644
index 00000000000..4aca5071625
--- /dev/null
+++ b/src/test/ui/suggestions/inner_type.rs
@@ -0,0 +1,40 @@
+// compile-flags: --edition=2021
+// run-rustfix
+
+pub struct Struct<T> {
+    pub p: T,
+}
+
+impl<T> Struct<T> {
+    pub fn method(&self) {}
+
+    pub fn some_mutable_method(&mut self) {}
+}
+
+fn main() {
+    let other_item = std::cell::RefCell::new(Struct { p: 42_u32 });
+
+    other_item.method();
+    //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599]
+    //~| HELP use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
+
+    other_item.some_mutable_method();
+    //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599]
+    //~| HELP .borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
+
+    let another_item = std::sync::Mutex::new(Struct { p: 42_u32 });
+
+    another_item.method();
+    //~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599]
+    //~| HELP use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+
+    let another_item = std::sync::RwLock::new(Struct { p: 42_u32 });
+
+    another_item.method();
+    //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599]
+    //~| HELP  use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+
+    another_item.some_mutable_method();
+    //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599]
+    //~| HELP use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+}
diff --git a/src/test/ui/suggestions/inner_type.stderr b/src/test/ui/suggestions/inner_type.stderr
new file mode 100644
index 00000000000..5ac3d04f104
--- /dev/null
+++ b/src/test/ui/suggestions/inner_type.stderr
@@ -0,0 +1,83 @@
+error[E0599]: no method named `method` found for struct `RefCell` in the current scope
+  --> $DIR/inner_type.rs:17:16
+   |
+LL |     other_item.method();
+   |                ^^^^^^ method not found in `RefCell<Struct<u32>>`
+   |
+note: the method `method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type.rs:9:5
+   |
+LL |     pub fn method(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: use `.borrow()` to borrow the `Struct<u32>`, panicking if a mutable borrow exists
+   |
+LL |     other_item.borrow().method();
+   |               +++++++++
+
+error[E0599]: no method named `some_mutable_method` found for struct `RefCell` in the current scope
+  --> $DIR/inner_type.rs:21:16
+   |
+LL |     other_item.some_mutable_method();
+   |                ^^^^^^^^^^^^^^^^^^^ method not found in `RefCell<Struct<u32>>`
+   |
+note: the method `some_mutable_method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type.rs:11:5
+   |
+LL |     pub fn some_mutable_method(&mut self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use `.borrow_mut()` to mutably borrow the `Struct<u32>`, panicking if any borrows exist
+   |
+LL |     other_item.borrow_mut().some_mutable_method();
+   |               +++++++++++++
+
+error[E0599]: no method named `method` found for struct `Mutex` in the current scope
+  --> $DIR/inner_type.rs:27:18
+   |
+LL |     another_item.method();
+   |                  ^^^^^^ method not found in `Mutex<Struct<u32>>`
+   |
+note: the method `method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type.rs:9:5
+   |
+LL |     pub fn method(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: use `.lock().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+   |
+LL |     another_item.lock().unwrap().method();
+   |                 ++++++++++++++++
+
+error[E0599]: no method named `method` found for struct `RwLock` in the current scope
+  --> $DIR/inner_type.rs:33:18
+   |
+LL |     another_item.method();
+   |                  ^^^^^^ method not found in `RwLock<Struct<u32>>`
+   |
+note: the method `method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type.rs:9:5
+   |
+LL |     pub fn method(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: use `.read().unwrap()` to borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+   |
+LL |     another_item.read().unwrap().method();
+   |                 ++++++++++++++++
+
+error[E0599]: no method named `some_mutable_method` found for struct `RwLock` in the current scope
+  --> $DIR/inner_type.rs:37:18
+   |
+LL |     another_item.some_mutable_method();
+   |                  ^^^^^^^^^^^^^^^^^^^ method not found in `RwLock<Struct<u32>>`
+   |
+note: the method `some_mutable_method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type.rs:11:5
+   |
+LL |     pub fn some_mutable_method(&mut self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: use `.write().unwrap()` to mutably borrow the `Struct<u32>`, blocking the current thread until it can be acquired
+   |
+LL |     another_item.write().unwrap().some_mutable_method();
+   |                 +++++++++++++++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/inner_type2.rs b/src/test/ui/suggestions/inner_type2.rs
new file mode 100644
index 00000000000..c56ea7c030d
--- /dev/null
+++ b/src/test/ui/suggestions/inner_type2.rs
@@ -0,0 +1,26 @@
+pub struct Struct<T> {
+    pub p: T,
+}
+
+impl<T> Struct<T> {
+    pub fn method(&self) {}
+
+    pub fn some_mutable_method(&mut self) {}
+}
+
+thread_local! {
+    static STRUCT: Struct<u32> = Struct {
+        p: 42_u32
+    };
+}
+
+fn main() {
+    STRUCT.method();
+    //~^ ERROR no method named `method` found for struct `LocalKey` in the current scope [E0599]
+    //~| HELP use `with` or `try_with` to access thread local storage
+
+    let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 });
+    item.method();
+    //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599]
+    //~| HELP if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
+}
diff --git a/src/test/ui/suggestions/inner_type2.stderr b/src/test/ui/suggestions/inner_type2.stderr
new file mode 100644
index 00000000000..eddfd9d6340
--- /dev/null
+++ b/src/test/ui/suggestions/inner_type2.stderr
@@ -0,0 +1,29 @@
+error[E0599]: no method named `method` found for struct `LocalKey` in the current scope
+  --> $DIR/inner_type2.rs:18:12
+   |
+LL |     STRUCT.method();
+   |            ^^^^^^ method not found in `LocalKey<Struct<u32>>`
+   |
+   = help: use `with` or `try_with` to access thread local storage
+note: the method `method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type2.rs:6:5
+   |
+LL |     pub fn method(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `method` found for union `MaybeUninit` in the current scope
+  --> $DIR/inner_type2.rs:23:10
+   |
+LL |     item.method();
+   |          ^^^^^^ method not found in `MaybeUninit<Struct<u32>>`
+   |
+   = help: if this `MaybeUninit::<Struct<u32>>` has been initialized, use one of the `assume_init` methods to access the inner value
+note: the method `method` exists on the type `Struct<u32>`
+  --> $DIR/inner_type2.rs:6:5
+   |
+LL |     pub fn method(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs
index dd52b315055..02b5fb61894 100644
--- a/src/test/ui/suggestions/issue-85347.rs
+++ b/src/test/ui/suggestions/issue-85347.rs
@@ -2,6 +2,7 @@ use std::ops::Deref;
 trait Foo {
     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
     //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+    //~| ERROR associated type bindings are not allowed here
     //~| HELP add missing
 }
 
diff --git a/src/test/ui/suggestions/issue-85347.stderr b/src/test/ui/suggestions/issue-85347.stderr
index de853de27e4..17c1b7dc4cc 100644
--- a/src/test/ui/suggestions/issue-85347.stderr
+++ b/src/test/ui/suggestions/issue-85347.stderr
@@ -14,6 +14,13 @@ help: add missing lifetime argument
 LL |     type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
    |                                              +++
 
-error: aborting due to previous error
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-85347.rs:3:46
+   |
+LL |     type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
+   |                                              ^^^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0229.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
index e5d2ead6ad6..872263fd731 100644
--- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
@@ -27,3 +27,4 @@ LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0311`.
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index ed1b91676a2..171f4b333db 100644
--- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -164,5 +164,5 @@ LL |     G: Get<T> + 'a,
 
 error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0261, E0309, E0621, E0700.
+Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700.
 For more information about an error, try `rustc --explain E0261`.
diff --git a/src/tools/miri/tests/fail/invalid_bool.rs b/src/tools/miri/tests/fail/invalid_bool.rs
index 525f8831c1c..dde414f4177 100644
--- a/src/tools/miri/tests/fail/invalid_bool.rs
+++ b/src/tools/miri/tests/fail/invalid_bool.rs
@@ -1,7 +1,7 @@
 // Validation makes this fail in the wrong place
 // Make sure we find these even with many checks disabled.
 //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
-#![feature(bench_black_box)]
+
 
 fn main() {
     let b = unsafe { std::mem::transmute::<u8, bool>(2) };
diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs
index 48dd99441eb..ce62fb0de04 100644
--- a/src/tools/miri/tests/pass/float.rs
+++ b/src/tools/miri/tests/pass/float.rs
@@ -1,4 +1,4 @@
-#![feature(stmt_expr_attributes, bench_black_box)]
+#![feature(stmt_expr_attributes)]
 #![allow(arithmetic_overflow)]
 use std::fmt::Debug;
 use std::hint::black_box;
diff --git a/src/tools/miri/tests/pass/u128.rs b/src/tools/miri/tests/pass/u128.rs
index 0ef7a514cb6..6def529dbe7 100644
--- a/src/tools/miri/tests/pass/u128.rs
+++ b/src/tools/miri/tests/pass/u128.rs
@@ -1,4 +1,3 @@
-#![feature(bench_black_box)]
 use std::hint::black_box as b;
 
 fn main() {