about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs79
-rw-r--r--compiler/rustc_hir/src/definitions.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs81
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs9
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs4
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs47
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs45
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs3
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs44
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs5
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs10
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_middle/src/query/keys.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs6
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs15
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs9
-rw-r--r--compiler/rustc_parse_format/src/lib.rs54
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs12
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs6
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs6
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs9
-rw-r--r--config.example.toml3
-rw-r--r--src/bootstrap/CHANGELOG.md1
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/defaults/config.codegen.toml2
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/bootstrap/native.rs9
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--tests/codegen-units/polymorphization/auxiliary/poly-dep.rs4
-rw-r--r--tests/codegen-units/polymorphization/poly-foreign.rs11
-rw-r--r--tests/ui/async-await/in-trait/async-associated-types.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-associated-types2.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr (renamed from tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr)4
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr17
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr (renamed from tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr)2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-extra.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr (renamed from tests/ui/async-await/in-trait/async-example-desugared-manual.stderr)2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr11
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-recursive-generic.current.stderr (renamed from tests/ui/async-await/in-trait/async-recursive-generic.stderr)2
-rw-r--r--tests/ui/async-await/in-trait/async-recursive-generic.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-recursive-generic.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-recursive.current.stderr (renamed from tests/ui/async-await/in-trait/async-recursive.stderr)2
-rw-r--r--tests/ui/async-await/in-trait/async-recursive.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/async-recursive.rs2
-rw-r--r--tests/ui/async-await/in-trait/bad-signatures.current.stderr (renamed from tests/ui/async-await/in-trait/bad-signatures.stderr)6
-rw-r--r--tests/ui/async-await/in-trait/bad-signatures.next.stderr26
-rw-r--r--tests/ui/async-await/in-trait/bad-signatures.rs2
-rw-r--r--tests/ui/async-await/in-trait/early-bound-1.rs2
-rw-r--r--tests/ui/async-await/in-trait/early-bound-2.rs2
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr (renamed from tests/ui/async-await/in-trait/fn-not-async-err2.stderr)2
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr12
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err2.rs2
-rw-r--r--tests/ui/async-await/in-trait/implied-bounds.rs2
-rw-r--r--tests/ui/async-await/in-trait/issue-102138.rs2
-rw-r--r--tests/ui/async-await/in-trait/issue-102219.rs2
-rw-r--r--tests/ui/async-await/in-trait/object-safety.current.stderr (renamed from tests/ui/async-await/in-trait/object-safety.stderr)6
-rw-r--r--tests/ui/async-await/in-trait/object-safety.next.stderr27
-rw-r--r--tests/ui/async-await/in-trait/object-safety.rs2
-rw-r--r--tests/ui/codegen/mono-impossible.rs13
-rw-r--r--tests/ui/fmt/auxiliary/format-string-proc-macro.rs36
-rw-r--r--tests/ui/fmt/format-args-capture-first-literal-is-macro.rs21
-rw-r--r--tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr30
-rw-r--r--tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs8
-rw-r--r--tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr12
-rw-r--r--tests/ui/fmt/format-args-capture-issue-106408.rs10
-rw-r--r--tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs16
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.rs9
-rw-r--r--tests/ui/fmt/respanned-literal-issue-106191.stderr21
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match-works.rs6
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match.current.stderr (renamed from tests/ui/impl-trait/in-trait/deep-match.stderr)4
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match.next.stderr15
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match.rs9
-rw-r--r--tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr (renamed from tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr11
-rw-r--r--tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/encode.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/foreign.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.current.stderr (renamed from tests/ui/impl-trait/in-trait/issue-102140.stderr)6
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.next.stderr33
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs17
-rw-r--r--tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.current.stderr (renamed from tests/ui/impl-trait/in-trait/object-safety.stderr)12
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.next.stderr50
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr (renamed from tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/reveal.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr (renamed from tests/ui/impl-trait/in-trait/signature-mismatch.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-substs-remap.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/success.rs2
-rw-r--r--tests/ui/implied-bounds/normalization.rs58
-rw-r--r--tests/ui/layout/transmute-to-tail-with-err.rs8
-rw-r--r--tests/ui/layout/transmute-to-tail-with-err.stderr14
-rw-r--r--tests/ui/suggestions/chain-method-call-mutation-in-place.rs6
-rw-r--r--tests/ui/suggestions/chain-method-call-mutation-in-place.stderr37
-rw-r--r--tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs11
-rw-r--r--tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr19
124 files changed, 989 insertions, 345 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index e93a23394c0..db2ef7fba4b 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -36,6 +36,21 @@ enum PositionUsedAs {
 }
 use PositionUsedAs::*;
 
+struct MacroInput {
+    fmtstr: P<Expr>,
+    args: FormatArguments,
+    /// Whether the first argument was a string literal or a result from eager macro expansion.
+    /// If it's not a string literal, we disallow implicit arugment capturing.
+    ///
+    /// This does not correspond to whether we can treat spans to the literal normally, as the whole
+    /// invocation might be the result of another macro expansion, in which case this flag may still be true.
+    ///
+    /// See [RFC 2795] for more information.
+    ///
+    /// [RFC 2795]: https://rust-lang.github.io/rfcs/2795-format-args-implicit-identifiers.html#macro-hygiene
+    is_direct_literal: bool,
+}
+
 /// Parses the arguments from the given list of tokens, returning the diagnostic
 /// if there's a parse error so we can continue parsing other format!
 /// expressions.
@@ -45,11 +60,7 @@ use PositionUsedAs::*;
 /// ```text
 /// Ok((fmtstr, parsed arguments))
 /// ```
-fn parse_args<'a>(
-    ecx: &mut ExtCtxt<'a>,
-    sp: Span,
-    tts: TokenStream,
-) -> PResult<'a, (P<Expr>, FormatArguments)> {
+fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, MacroInput> {
     let mut args = FormatArguments::new();
 
     let mut p = ecx.new_parser_from_tts(tts);
@@ -59,25 +70,21 @@ fn parse_args<'a>(
     }
 
     let first_token = &p.token;
-    let fmtstr = match first_token.kind {
-        token::TokenKind::Literal(token::Lit {
-            kind: token::LitKind::Str | token::LitKind::StrRaw(_),
-            ..
-        }) => {
-            // If the first token is a string literal, then a format expression
-            // is constructed from it.
-            //
-            // This allows us to properly handle cases when the first comma
-            // after the format string is mistakenly replaced with any operator,
-            // which cause the expression parser to eat too much tokens.
-            p.parse_literal_maybe_minus()?
-        }
-        _ => {
-            // Otherwise, we fall back to the expression parser.
-            p.parse_expr()?
-        }
+
+    let fmtstr = if let token::Literal(lit) = first_token.kind && matches!(lit.kind, token::Str | token::StrRaw(_)) {
+        // This allows us to properly handle cases when the first comma
+        // after the format string is mistakenly replaced with any operator,
+        // which cause the expression parser to eat too much tokens.
+        p.parse_literal_maybe_minus()?
+    } else {
+        // Otherwise, we fall back to the expression parser.
+        p.parse_expr()?
     };
 
+    // Only allow implicit captures to be used when the argument is a direct literal
+    // instead of a macro expanding to one.
+    let is_direct_literal = matches!(fmtstr.kind, ExprKind::Lit(_));
+
     let mut first = true;
 
     while p.token != token::Eof {
@@ -147,17 +154,19 @@ fn parse_args<'a>(
             }
         }
     }
-    Ok((fmtstr, args))
+    Ok(MacroInput { fmtstr, args, is_direct_literal })
 }
 
-pub fn make_format_args(
+fn make_format_args(
     ecx: &mut ExtCtxt<'_>,
-    efmt: P<Expr>,
-    mut args: FormatArguments,
+    input: MacroInput,
     append_newline: bool,
 ) -> Result<FormatArgs, ()> {
     let msg = "format argument must be a string literal";
-    let unexpanded_fmt_span = efmt.span;
+    let unexpanded_fmt_span = input.fmtstr.span;
+
+    let MacroInput { fmtstr: efmt, mut args, is_direct_literal } = input;
+
     let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) {
         Ok(mut fmt) if append_newline => {
             fmt.0 = Symbol::intern(&format!("{}\n", fmt.0));
@@ -208,11 +217,11 @@ pub fn make_format_args(
         }
     }
 
-    let is_literal = parser.is_literal;
+    let is_source_literal = parser.is_source_literal;
 
     if !parser.errors.is_empty() {
         let err = parser.errors.remove(0);
-        let sp = if is_literal {
+        let sp = if is_source_literal {
             fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end))
         } else {
             // The format string could be another macro invocation, e.g.:
@@ -230,7 +239,7 @@ pub fn make_format_args(
         if let Some(note) = err.note {
             e.note(&note);
         }
-        if let Some((label, span)) = err.secondary_label && is_literal {
+        if let Some((label, span)) = err.secondary_label && is_source_literal {
             e.span_label(fmt_span.from_inner(InnerSpan::new(span.start, span.end)), label);
         }
         if err.should_be_replaced_with_positional_argument {
@@ -256,7 +265,7 @@ pub fn make_format_args(
     }
 
     let to_span = |inner_span: rustc_parse_format::InnerSpan| {
-        is_literal.then(|| {
+        is_source_literal.then(|| {
             fmt_span.from_inner(InnerSpan { start: inner_span.start, end: inner_span.end })
         })
     };
@@ -304,7 +313,7 @@ pub fn make_format_args(
                     // Name not found in `args`, so we add it as an implicitly captured argument.
                     let span = span.unwrap_or(fmt_span);
                     let ident = Ident::new(name, span);
-                    let expr = if is_literal {
+                    let expr = if is_direct_literal {
                         ecx.expr_ident(span, ident)
                     } else {
                         // For the moment capturing variables from format strings expanded from macros is
@@ -814,7 +823,7 @@ fn report_invalid_references(
         // for `println!("{7:7$}", 1);`
         indexes.sort();
         indexes.dedup();
-        let span: MultiSpan = if !parser.is_literal || parser.arg_places.is_empty() {
+        let span: MultiSpan = if !parser.is_source_literal || parser.arg_places.is_empty() {
             MultiSpan::from_span(fmt_span)
         } else {
             MultiSpan::from_spans(invalid_refs.iter().filter_map(|&(_, span, _, _)| span).collect())
@@ -855,8 +864,8 @@ fn expand_format_args_impl<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     sp = ecx.with_def_site_ctxt(sp);
     match parse_args(ecx, sp, tts) {
-        Ok((efmt, args)) => {
-            if let Ok(format_args) = make_format_args(ecx, efmt, args, nl) {
+        Ok(input) => {
+            if let Ok(format_args) = make_format_args(ecx, input, nl) {
                 MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args))))
             } else {
                 MacEager::expr(DummyResult::raw_expr(sp, true))
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 8ceb176491b..3c4fc9cb530 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -404,8 +404,12 @@ impl DefPathData {
         match *self {
             TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
 
+            // We use this name when collecting `ModChild`s.
+            // FIXME this could probably be removed with some refactoring to the name resolver.
+            ImplTraitAssocTy => Some(kw::Empty),
+
             Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
-            | ImplTrait | ImplTraitAssocTy => None,
+            | ImplTrait => None,
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 3cd4c4afe86..f830269b45d 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1440,6 +1440,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             tcx.associated_items(pred.def_id())
                                 .in_definition_order()
                                 .filter(|item| item.kind == ty::AssocKind::Type)
+                                .filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
                                 .map(|item| item.def_id),
                         );
                     }
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 6e6f8c1533b..123207249d2 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -330,7 +330,6 @@ fn compare_method_predicate_entailment<'tcx>(
     // lifetime parameters.
     let outlives_env = OutlivesEnvironment::with_bounds(
         param_env,
-        Some(infcx),
         infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()),
     );
     infcx.process_registered_region_obligations(
@@ -728,7 +727,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // lifetime parameters.
     let outlives_environment = OutlivesEnvironment::with_bounds(
         param_env,
-        Some(infcx),
         infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys),
     );
     infcx
@@ -2058,8 +2056,7 @@ pub(super) fn check_type_bounds<'tcx>(
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
     let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types);
-    let outlives_environment =
-        OutlivesEnvironment::with_bounds(param_env, Some(&infcx), implied_bounds);
+    let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
 
     infcx.err_ctxt().check_region_obligations_and_report_errors(
         impl_ty.def_id.expect_local(),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 71050864ce0..28f0924d1d6 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -115,8 +115,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
         return;
     }
 
-    let outlives_environment =
-        OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
+    let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
 
     let _ = infcx
         .err_ctxt()
@@ -676,7 +675,6 @@ fn resolve_regions_with_wf_tys<'tcx>(
     let infcx = tcx.infer_ctxt().build();
     let outlives_environment = OutlivesEnvironment::with_bounds(
         param_env,
-        Some(&infcx),
         infcx.implied_bounds_tys(param_env, id, wf_tys.clone()),
     );
     let region_bound_pairs = outlives_environment.region_bound_pairs();
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index e9963e67741..465ae047de3 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1427,25 +1427,25 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             if let ResolvedArg::LateBound(..) = def && crossed_anon_const {
                 let use_span = self.tcx.hir().span(hir_id);
                 let def_span = self.tcx.def_span(param_def_id);
-                match self.tcx.def_kind(param_def_id) {
+                let guar = match self.tcx.def_kind(param_def_id) {
                     DefKind::ConstParam => {
                         self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const {
                             use_span,
                             def_span,
-                        });
+                        })
                     }
                     DefKind::TyParam => {
                         self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type {
                             use_span,
                             def_span,
-                        });
+                        })
                     }
                     _ => unreachable!(),
-                }
-                return;
+                };
+                self.map.defs.insert(hir_id, ResolvedArg::Error(guar));
+            } else {
+                self.map.defs.insert(hir_id, def);
             }
-
-            self.map.defs.insert(hir_id, def);
             return;
         }
 
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 58dd03811f7..1c5860e97bc 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -179,7 +179,7 @@ fn get_impl_substs(
     }
 
     let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types);
-    let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
+    let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
     let _ =
         infcx.err_ctxt().check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
     let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 7ba57b3b7a2..0ec10dc9ea3 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -83,7 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.annotate_expected_due_to_let_ty(err, expr, error);
         self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
         self.note_type_is_not_clone(err, expected, expr_ty, expr);
-        self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
+        self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty);
         self.check_for_range_as_method_call(err, expr, expr_ty, expected);
         self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected);
         self.check_wrong_return_type_due_to_generic_arg(err, expr, expr_ty);
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 4720306e159..ac73cd7cc6e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -950,44 +950,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
-        expected: Ty<'tcx>,
+        expected: Option<Ty<'tcx>>,
         found: Ty<'tcx>,
     ) {
         if found != self.tcx.types.unit {
             return;
         }
-        if let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind {
-            if self
-                .typeck_results
+
+        let ExprKind::MethodCall(path_segment, rcvr, ..) = expr.kind else {
+            return;
+        };
+
+        let rcvr_has_the_expected_type = self
+            .typeck_results
+            .borrow()
+            .expr_ty_adjusted_opt(rcvr)
+            .and_then(|ty| expected.map(|expected_ty| expected_ty.peel_refs() == ty.peel_refs()))
+            .unwrap_or(false);
+
+        let prev_call_mutates_and_returns_unit = || {
+            self.typeck_results
                 .borrow()
-                .expr_ty_adjusted_opt(rcvr)
-                .map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
-            {
-                return;
-            }
-            let mut sp = MultiSpan::from_span(path_segment.ident.span);
-            sp.push_span_label(
-                path_segment.ident.span,
-                format!(
-                    "this call modifies {} in-place",
-                    match rcvr.kind {
-                        ExprKind::Path(QPath::Resolved(
-                            None,
-                            hir::Path { segments: [segment], .. },
-                        )) => format!("`{}`", segment.ident),
-                        _ => "its receiver".to_string(),
-                    }
-                ),
-            );
+                .type_dependent_def_id(expr.hir_id)
+                .map(|def_id| self.tcx.fn_sig(def_id).skip_binder().skip_binder())
+                .and_then(|sig| sig.inputs_and_output.split_last())
+                .map(|(output, inputs)| {
+                    output.is_unit()
+                        && inputs
+                            .get(0)
+                            .and_then(|self_ty| self_ty.ref_mutability())
+                            .map_or(false, rustc_ast::Mutability::is_mut)
+                })
+                .unwrap_or(false)
+        };
+
+        if !(rcvr_has_the_expected_type || prev_call_mutates_and_returns_unit()) {
+            return;
+        }
+
+        let mut sp = MultiSpan::from_span(path_segment.ident.span);
+        sp.push_span_label(
+            path_segment.ident.span,
+            format!(
+                "this call modifies {} in-place",
+                match rcvr.kind {
+                    ExprKind::Path(QPath::Resolved(
+                        None,
+                        hir::Path { segments: [segment], .. },
+                    )) => format!("`{}`", segment.ident),
+                    _ => "its receiver".to_string(),
+                }
+            ),
+        );
+
+        let modifies_rcvr_note =
+            format!("method `{}` modifies its receiver in-place", path_segment.ident);
+        if rcvr_has_the_expected_type {
             sp.push_span_label(
                 rcvr.span,
                 "you probably want to use this value after calling the method...",
             );
+            err.span_note(sp, &modifies_rcvr_note);
+            err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
+        } else if let ExprKind::MethodCall(..) = rcvr.kind {
             err.span_note(
                 sp,
-                &format!("method `{}` modifies its receiver in-place", path_segment.ident),
+                modifies_rcvr_note.clone() + ", it is not meant to be used in method chains.",
             );
-            err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
+        } else {
+            err.span_note(sp, &modifies_rcvr_note);
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 7055d9257ec..50f2b71250c 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -416,6 +416,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
                 probe.is_ok()
             });
+
+            self.note_internal_mutation_in_method(
+                &mut err,
+                rcvr_expr,
+                expected.to_option(&self),
+                rcvr_ty,
+            );
         }
 
         let mut custom_span_label = false;
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index c36c75e4443..11ff65d0c37 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -238,15 +238,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Note that there are two tests to check that this remains true
         // (`regions-reassign-{match,let}-bound-pointer.rs`).
         //
-        // 2. Things go horribly wrong if we use subtype. The reason for
-        // THIS is a fairly subtle case involving bound regions. See the
-        // `givens` field in `region_constraints`, as well as the test
+        // 2. An outdated issue related to the old HIR borrowck. See the test
         // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
-        // for details. Short version is that we must sometimes detect
-        // relationships between specific region variables and regions
-        // bound in a closure signature, and that detection gets thrown
-        // off when we substitute fresh region variables here to enable
-        // subtyping.
     }
 
     /// Compute the new expected type and default binding mode from the old ones
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 436d29c2449..90e89a18782 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -636,11 +636,9 @@ pub fn make_query_region_constraints<'tcx>(
     outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>, ConstraintCategory<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
 ) -> QueryRegionConstraints<'tcx> {
-    let RegionConstraintData { constraints, verifys, givens, member_constraints } =
-        region_constraints;
+    let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints;
 
     assert!(verifys.is_empty());
-    assert!(givens.is_empty());
 
     debug!(?constraints);
 
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 2c480355085..cf657756ff5 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 };
 use rustc_data_structures::intern::Interned;
-use rustc_index::vec::{Idx, IndexVec};
+use rustc_index::vec::IndexVec;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::PlaceholderRegion;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -132,7 +132,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         }
 
         let graph = self.construct_graph();
-        self.expand_givens(&graph);
         self.expansion(&mut var_data);
         self.collect_errors(&mut var_data, errors);
         self.collect_var_errors(&var_data, &graph, errors);
@@ -164,38 +163,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         }
     }
 
-    fn expand_givens(&mut self, graph: &RegionGraph<'_>) {
-        // Givens are a kind of horrible hack to account for
-        // constraints like 'c <= '0 that are known to hold due to
-        // closure signatures (see the comment above on the `givens`
-        // field). They should go away. But until they do, the role
-        // of this fn is to account for the transitive nature:
-        //
-        //     Given 'c <= '0
-        //     and   '0 <= '1
-        //     then  'c <= '1
-
-        let seeds: Vec<_> = self.data.givens.iter().cloned().collect();
-        for (r, vid) in seeds {
-            // While all things transitively reachable in the graph
-            // from the variable (`'0` in the example above).
-            let seed_index = NodeIndex(vid.index() as usize);
-            for succ_index in graph.depth_traverse(seed_index, OUTGOING) {
-                let succ_index = succ_index.0;
-
-                // The first N nodes correspond to the region
-                // variables. Other nodes correspond to constant
-                // regions.
-                if succ_index < self.num_vars() {
-                    let succ_vid = RegionVid::new(succ_index);
-
-                    // Add `'c <= '1`.
-                    self.data.givens.insert((r, succ_vid));
-                }
-            }
-        }
-    }
-
     /// Gets the LUb of a given region and the empty region
     fn lub_empty(&self, a_region: Region<'tcx>) -> Result<Region<'tcx>, PlaceholderRegion> {
         match *a_region {
@@ -362,18 +329,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
     ) -> bool {
         debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data);
 
-        match *a_region {
-            // Check if this relationship is implied by a given.
-            ty::ReEarlyBound(_) | ty::ReFree(_) => {
-                if self.data.givens.contains(&(a_region, b_vid)) {
-                    debug!("given");
-                    return false;
-                }
-            }
-
-            _ => {}
-        }
-
         match *b_data {
             VarValue::Empty(empty_ui) => {
                 let lub = match self.lub_empty(a_region) {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4a834957959..66fb1db4618 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -855,10 +855,6 @@ impl<'tcx> InferCtxt<'tcx> {
         self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
     }
 
-    pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
-        self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
-    }
-
     pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
     where
         T: at::ToTrace<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index 24e3c34dd94..a480ee5429e 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -1,9 +1,9 @@
 use crate::infer::free_regions::FreeRegionMap;
-use crate::infer::{GenericKind, InferCtxt};
+use crate::infer::GenericKind;
 use crate::traits::query::OutlivesBound;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
-use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
+use rustc_middle::ty::{self, Region};
 
 use super::explicit_outlives_bounds;
 
@@ -75,7 +75,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
             region_bound_pairs: Default::default(),
         };
 
-        builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
+        builder.add_outlives_bounds(explicit_outlives_bounds(param_env));
 
         builder
     }
@@ -89,11 +89,10 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
     /// Create a new `OutlivesEnvironment` with extra outlives bounds.
     pub fn with_bounds(
         param_env: ty::ParamEnv<'tcx>,
-        infcx: Option<&InferCtxt<'tcx>>,
         extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
     ) -> Self {
         let mut builder = Self::builder(param_env);
-        builder.add_outlives_bounds(infcx, extra_bounds);
+        builder.add_outlives_bounds(extra_bounds);
         builder.build()
     }
 
@@ -120,12 +119,7 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
     }
 
     /// Processes outlives bounds that are known to hold, whether from implied or other sources.
-    ///
-    /// The `infcx` parameter is optional; if the implied bounds may
-    /// contain inference variables, it must be supplied, in which
-    /// case we will register "givens" on the inference context. (See
-    /// `RegionConstraintData`.)
-    fn add_outlives_bounds<I>(&mut self, infcx: Option<&InferCtxt<'tcx>>, outlives_bounds: I)
+    fn add_outlives_bounds<I>(&mut self, outlives_bounds: I)
     where
         I: IntoIterator<Item = OutlivesBound<'tcx>>,
     {
@@ -142,27 +136,14 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> {
                     self.region_bound_pairs
                         .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
                 }
-                OutlivesBound::RegionSubRegion(r_a, r_b) => {
-                    if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {
-                        infcx
-                            .expect("no infcx provided but region vars found")
-                            .add_given(r_a, vid_b);
-                    } else {
-                        // In principle, we could record (and take
-                        // advantage of) every relationship here, but
-                        // we are also free not to -- it simply means
-                        // strictly less that we can successfully type
-                        // check. Right now we only look for things
-                        // relationships between free regions. (It may
-                        // also be that we should revise our inference
-                        // system to be more general and to make use
-                        // of *every* relationship that arises here,
-                        // but presently we do not.)
-                        if r_a.is_free_or_static() && r_b.is_free() {
-                            self.region_relation.add(r_a, r_b)
-                        }
-                    }
-                }
+                OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
+                    (
+                        ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_),
+                        ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_),
+                    ) => self.region_relation.add(r_a, r_b),
+                    (ty::ReError(_), _) | (_, ty::ReError(_)) => {}
+                    _ => bug!("add_outlives_bounds: unexpected regions"),
+                },
             }
         }
     }
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index e413b2bb570..89ada23c667 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -424,9 +424,6 @@ impl<'tcx> MiniGraph<'tcx> {
                 &AddConstraint(Constraint::RegSubReg(a, b)) => {
                     each_edge(a, b);
                 }
-                &AddGiven(a, b) => {
-                    each_edge(a, tcx.mk_re_var(b));
-                }
                 &AddVerify(i) => span_bug!(
                     verifys[i].origin.span(),
                     "we never add verifications while doing higher-ranked things",
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index 0b86d9c1fb8..7b272dfd2a4 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -7,7 +7,7 @@ use super::{
     InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin,
 };
 
-use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::undo_log::UndoLogs;
@@ -104,26 +104,6 @@ pub struct RegionConstraintData<'tcx> {
     /// An example is a `A <= B` where neither `A` nor `B` are
     /// inference variables.
     pub verifys: Vec<Verify<'tcx>>,
-
-    /// A "given" is a relationship that is known to hold. In
-    /// particular, we often know from closure fn signatures that a
-    /// particular free region must be a subregion of a region
-    /// variable:
-    ///
-    ///    foo.iter().filter(<'a> |x: &'a &'b T| ...)
-    ///
-    /// In situations like this, `'b` is in fact a region variable
-    /// introduced by the call to `iter()`, and `'a` is a bound region
-    /// on the closure (as indicated by the `<'a>` prefix). If we are
-    /// naive, we wind up inferring that `'b` must be `'static`,
-    /// because we require that it be greater than `'a` and we do not
-    /// know what `'a` is precisely.
-    ///
-    /// This hashmap is used to avoid that naive scenario. Basically
-    /// we record the fact that `'a <= 'b` is implied by the fn
-    /// signature, and then ignore the constraint when solving
-    /// equations. This is a bit of a hack but seems to work.
-    pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>,
 }
 
 /// Represents a constraint that influences the inference process.
@@ -297,9 +277,6 @@ pub(crate) enum UndoLog<'tcx> {
     /// We added the given `verify`.
     AddVerify(usize),
 
-    /// We added the given `given`.
-    AddGiven(Region<'tcx>, ty::RegionVid),
-
     /// We added a GLB/LUB "combination variable".
     AddCombination(CombineMapType, TwoRegions<'tcx>),
 }
@@ -348,9 +325,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> {
                 self.data.verifys.pop();
                 assert_eq!(self.data.verifys.len(), index);
             }
-            AddGiven(sub, sup) => {
-                self.data.givens.remove(&(sub, sup));
-            }
             AddCombination(Glb, ref regions) => {
                 self.glbs.remove(regions);
             }
@@ -492,15 +466,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
         self.undo_log.push(AddVerify(index));
     }
 
-    pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) {
-        // cannot add givens once regions are resolved
-        if self.data.givens.insert((sub, sup)) {
-            debug!("add_given({:?} <= {:?})", sub, sup);
-
-            self.undo_log.push(AddGiven(sub, sup));
-        }
-    }
-
     pub(super) fn make_eqregion(
         &mut self,
         origin: SubregionOrigin<'tcx>,
@@ -804,11 +769,8 @@ impl<'tcx> RegionConstraintData<'tcx> {
     /// Returns `true` if this region constraint data contains no constraints, and `false`
     /// otherwise.
     pub fn is_empty(&self) -> bool {
-        let RegionConstraintData { constraints, member_constraints, verifys, givens } = self;
-        constraints.is_empty()
-            && member_constraints.is_empty()
-            && verifys.is_empty()
-            && givens.is_empty()
+        let RegionConstraintData { constraints, member_constraints, verifys } = self;
+        constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty()
     }
 }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index ca26e1497aa..0070e46ffdf 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1087,6 +1087,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
         };
         let container = self.root.tables.assoc_container.get(self, id).unwrap();
+        let opt_rpitit_info =
+            self.root.tables.opt_rpitit_info.get(self, id).map(|d| d.decode(self));
 
         ty::AssocItem {
             name,
@@ -1095,8 +1097,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             trait_item_def_id: self.get_trait_item_def_id(id),
             container,
             fn_has_self_parameter: has_self,
-            // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): We need to encode this
-            opt_rpitit_info: None,
+            opt_rpitit_info,
         }
     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 6c5e8863010..a9843395336 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -226,7 +226,15 @@ provide! { tcx, def_id, other, cdata,
     lookup_default_body_stability => { table }
     lookup_deprecation_entry => { table }
     params_in_repr => { table }
-    unused_generic_params => { table }
+    // FIXME: Could be defaulted, but `LazyValue<UnusedGenericParams>` is not `FixedSizeEncoding`..
+    unused_generic_params => {
+        cdata
+            .root
+            .tables
+            .unused_generic_params
+            .get(cdata, def_id.index)
+            .map_or_else(|| ty::UnusedGenericParams::new_all_used(), |lazy| lazy.decode((cdata, tcx)))
+    }
     opt_def_kind => { table_direct }
     impl_parent => { table }
     impl_polarity => { table_direct }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index bbab8a62a2b..9649ce2c5a7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1350,19 +1350,24 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         if trait_item.kind == ty::AssocKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
+        if let Some(rpitit_info) = trait_item.opt_rpitit_info {
+            let rpitit_info = self.lazy(rpitit_info);
+            self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info);
+        }
     }
 
     fn encode_info_for_impl_item(&mut self, def_id: DefId) {
         debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
         let tcx = self.tcx;
 
-        let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
-        self.tables.impl_defaultness.set_some(def_id.index, ast_item.defaultness);
+        let defaultness = self.tcx.impl_defaultness(def_id.expect_local());
+        self.tables.impl_defaultness.set_some(def_id.index, defaultness);
         let impl_item = self.tcx.associated_item(def_id);
         self.tables.assoc_container.set_some(def_id.index, impl_item.container);
 
         match impl_item.kind {
             ty::AssocKind::Fn => {
+                let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
                 let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
                 self.tables.asyncness.set_some(def_id.index, sig.header.asyncness);
                 record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
@@ -1383,6 +1388,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
         }
+        if let Some(rpitit_info) = impl_item.opt_rpitit_info {
+            let rpitit_info = self.lazy(rpitit_info);
+            self.tables.opt_rpitit_info.set_some(def_id.index, rpitit_info);
+        }
     }
 
     fn encode_mir(&mut self) {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 1d2541a6788..e71a1c98102 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -355,6 +355,7 @@ define_tables! {
     inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
     associated_items_for_impl_trait_in_trait: Table<DefIndex, LazyArray<DefId>>,
+    opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
 
 - optional:
     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 746cf488589..8a4c10cd71c 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -316,7 +316,7 @@ impl<'hir> Map<'hir> {
     /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
     #[inline]
     pub fn find_by_def_id(self, id: LocalDefId) -> Option<Node<'hir>> {
-        self.find(self.local_def_id_to_hir_id(id))
+        self.find(self.tcx.opt_local_def_id_to_hir_id(id)?)
     }
 
     /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
@@ -333,7 +333,7 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
-        id.as_local().and_then(|id| self.find(self.local_def_id_to_hir_id(id)))
+        id.as_local().and_then(|id| self.find(self.tcx.opt_local_def_id_to_hir_id(id)?))
     }
 
     pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 78ee8a6a8fd..6e961a775c1 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -63,7 +63,7 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {
 
     #[inline(always)]
     fn query_crate_is_local(&self) -> bool {
-        true
+        self.def_id().is_local()
     }
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
@@ -76,7 +76,7 @@ impl<'tcx> Key for ty::Instance<'tcx> {
 
     #[inline(always)]
     fn query_crate_is_local(&self) -> bool {
-        true
+        self.def_id().is_local()
     }
 
     fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 254ffc33c96..42fb5d031bb 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -730,7 +730,11 @@ where
                         */
                     };
 
-                    let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
+                    let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type()
+                        // Projection eagerly bails out when the pointee references errors,
+                        // fall back to structurally deducing metadata.
+                        && !pointee.references_error()
+                    {
                         let metadata = tcx.normalize_erasing_regions(
                             cx.param_env(),
                             tcx.mk_projection(metadata_def_id, [pointee]),
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 8849e7eab33..7534d06ae91 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -63,6 +63,7 @@ trivially_parameterized_over_tcx! {
     ty::DeducedParamAttrs,
     ty::Generics,
     ty::ImplPolarity,
+    ty::ImplTraitInTraitData,
     ty::ReprOptions,
     ty::TraitDef,
     ty::UnusedGenericParams,
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index f529944acce..aff27e5664b 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1326,6 +1326,21 @@ fn create_mono_items_for_default_impls<'tcx>(
         return;
     }
 
+    // Unlike 'lazy' monomorphization that begins by collecting items transitively
+    // called by `main` or other global items, when eagerly monomorphizing impl
+    // items, we never actually check that the predicates of this impl are satisfied
+    // in a empty reveal-all param env (i.e. with no assumptions).
+    //
+    // Even though this impl has no substitutions, because we don't consider higher-
+    // ranked predicates such as `for<'a> &'a mut [u8]: Copy` to be trivially false,
+    // we must now check that the impl has no impossible-to-satisfy predicates.
+    if tcx.subst_and_check_impossible_predicates((
+        item.owner_id.to_def_id(),
+        &InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id()),
+    )) {
+        return;
+    }
+
     let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else {
         return;
     };
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index b7c3dbcc091..63263a642ac 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -36,6 +36,8 @@ fn unused_generic_params<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: ty::InstanceDef<'tcx>,
 ) -> UnusedGenericParams {
+    assert!(instance.def_id().is_local());
+
     if !tcx.sess.opts.unstable_opts.polymorphize {
         // If polymorphization disabled, then all parameters are used.
         return UnusedGenericParams::new_all_used();
@@ -100,13 +102,6 @@ fn should_polymorphize<'tcx>(
         return false;
     }
 
-    // Polymorphization results are stored in cross-crate metadata only when there are unused
-    // parameters, so assume that non-local items must have only used parameters (else this query
-    // would not be invoked, and the cross-crate metadata used instead).
-    if !def_id.is_local() {
-        return false;
-    }
-
     // Foreign items have no bodies to analyze.
     if tcx.is_foreign_item(def_id) {
         return false;
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 8a3cedfee79..1c5410c5658 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -14,6 +14,7 @@
 // We want to be able to build this crate with a stable compiler, so no
 // `#![feature]` attributes should be added.
 
+use rustc_lexer::unescape;
 pub use Alignment::*;
 pub use Count::*;
 pub use Piece::*;
@@ -234,8 +235,10 @@ pub struct Parser<'a> {
     last_opening_brace: Option<InnerSpan>,
     /// Whether the source string is comes from `println!` as opposed to `format!` or `print!`
     append_newline: bool,
-    /// Whether this formatting string is a literal or it comes from a macro.
-    pub is_literal: bool,
+    /// Whether this formatting string was written directly in the source. This controls whether we
+    /// can use spans to refer into it and give better error messages.
+    /// N.B: This does _not_ control whether implicit argument captures can be used.
+    pub is_source_literal: bool,
     /// Start position of the current line.
     cur_line_start: usize,
     /// Start and end byte offset of every line of the format string. Excludes
@@ -262,7 +265,7 @@ impl<'a> Iterator for Parser<'a> {
                     } else {
                         let arg = self.argument(lbrace_end);
                         if let Some(rbrace_pos) = self.must_consume('}') {
-                            if self.is_literal {
+                            if self.is_source_literal {
                                 let lbrace_byte_pos = self.to_span_index(pos);
                                 let rbrace_byte_pos = self.to_span_index(rbrace_pos);
 
@@ -302,7 +305,7 @@ impl<'a> Iterator for Parser<'a> {
                 _ => Some(String(self.string(pos))),
             }
         } else {
-            if self.is_literal {
+            if self.is_source_literal {
                 let span = self.span(self.cur_line_start, self.input.len());
                 if self.line_spans.last() != Some(&span) {
                     self.line_spans.push(span);
@@ -322,8 +325,8 @@ impl<'a> Parser<'a> {
         append_newline: bool,
         mode: ParseMode,
     ) -> Parser<'a> {
-        let input_string_kind = find_width_map_from_snippet(snippet, style);
-        let (width_map, is_literal) = match input_string_kind {
+        let input_string_kind = find_width_map_from_snippet(s, snippet, style);
+        let (width_map, is_source_literal) = match input_string_kind {
             InputStringKind::Literal { width_mappings } => (width_mappings, true),
             InputStringKind::NotALiteral => (Vec::new(), false),
         };
@@ -339,7 +342,7 @@ impl<'a> Parser<'a> {
             width_map,
             last_opening_brace: None,
             append_newline,
-            is_literal,
+            is_source_literal,
             cur_line_start: 0,
             line_spans: vec![],
         }
@@ -532,13 +535,13 @@ impl<'a> Parser<'a> {
                 '{' | '}' => {
                     return &self.input[start..pos];
                 }
-                '\n' if self.is_literal => {
+                '\n' if self.is_source_literal => {
                     self.line_spans.push(self.span(self.cur_line_start, pos));
                     self.cur_line_start = pos + 1;
                     self.cur.next();
                 }
                 _ => {
-                    if self.is_literal && pos == self.cur_line_start && c.is_whitespace() {
+                    if self.is_source_literal && pos == self.cur_line_start && c.is_whitespace() {
                         self.cur_line_start = pos + c.len_utf8();
                     }
                     self.cur.next();
@@ -890,6 +893,7 @@ impl<'a> Parser<'a> {
 /// written code (code snippet) and the `InternedString` that gets processed in the `Parser`
 /// in order to properly synthesise the intra-string `Span`s for error diagnostics.
 fn find_width_map_from_snippet(
+    input: &str,
     snippet: Option<string::String>,
     str_style: Option<usize>,
 ) -> InputStringKind {
@@ -902,8 +906,27 @@ fn find_width_map_from_snippet(
         return InputStringKind::Literal { width_mappings: Vec::new() };
     }
 
+    // Strip quotes.
     let snippet = &snippet[1..snippet.len() - 1];
 
+    // Macros like `println` add a newline at the end. That technically doens't make them "literals" anymore, but it's fine
+    // since we will never need to point our spans there, so we lie about it here by ignoring it.
+    // Since there might actually be newlines in the source code, we need to normalize away all trailing newlines.
+    // If we only trimmed it off the input, `format!("\n")` would cause a mismatch as here we they actually match up.
+    // Alternatively, we could just count the trailing newlines and only trim one from the input if they don't match up.
+    let input_no_nl = input.trim_end_matches('\n');
+    let Some(unescaped) = unescape_string(snippet) else {
+        return InputStringKind::NotALiteral;
+    };
+
+    let unescaped_no_nl = unescaped.trim_end_matches('\n');
+
+    if unescaped_no_nl != input_no_nl {
+        // The source string that we're pointing at isn't our input, so spans pointing at it will be incorrect.
+        // This can for example happen with proc macros that respan generated literals.
+        return InputStringKind::NotALiteral;
+    }
+
     let mut s = snippet.char_indices();
     let mut width_mappings = vec![];
     while let Some((pos, c)) = s.next() {
@@ -986,6 +1009,19 @@ fn find_width_map_from_snippet(
     InputStringKind::Literal { width_mappings }
 }
 
+fn unescape_string(string: &str) -> Option<string::String> {
+    let mut buf = string::String::new();
+    let mut ok = true;
+    unescape::unescape_literal(string, unescape::Mode::Str, &mut |_, unescaped_char| {
+        match unescaped_char {
+            Ok(c) => buf.push(c),
+            Err(_) => ok = false,
+        }
+    });
+
+    ok.then_some(buf)
+}
+
 // Assert a reasonable size for `Piece`
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Piece<'_>, 16);
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0d86a3032a6..f3304e91429 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1115,6 +1115,7 @@ supported_targets! {
     // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia
     ("aarch64-fuchsia", aarch64_fuchsia),
     ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
+    ("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia),
     // FIXME(#106649): Remove x86_64-fuchsia in favor of x86_64-unknown-fuchsia
     ("x86_64-fuchsia", x86_64_fuchsia),
     ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs
new file mode 100644
index 00000000000..ab7c08958fa
--- /dev/null
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs
@@ -0,0 +1,19 @@
+use crate::spec::{CodeModel, SanitizerSet, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "riscv64gc-unknown-fuchsia".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
+        arch: "riscv64".into(),
+        options: TargetOptions {
+            code_model: Some(CodeModel::Medium),
+            cpu: "generic-rv64".into(),
+            features: "+m,+a,+f,+d,+c".into(),
+            llvm_abiname: "lp64d".into(),
+            max_atomic_width: Some(64),
+            supported_sanitizers: SanitizerSet::SHADOWCALLSTACK,
+            ..super::fuchsia_base::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 96a4b76af55..aeaade1d66c 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -388,7 +388,6 @@ fn resolve_negative_obligation<'tcx>(
     let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id);
     let outlives_env = OutlivesEnvironment::with_bounds(
         param_env,
-        Some(&infcx),
         infcx.implied_bounds_tys(param_env, body_def_id, wf_tys),
     );
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index b3bf9ad599a..277926688e2 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -144,6 +144,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_ref: ty::PolyTraitRef<'tcx>,
         obligation: &PredicateObligation<'tcx>,
     ) -> OnUnimplementedNote {
+        if self.tcx.opt_rpitit_info(obligation.cause.body_id.to_def_id()).is_some() {
+            return OnUnimplementedNote::default();
+        }
+
         let (def_id, substs) = self
             .impl_similar_to(trait_ref, obligation)
             .unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs));
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 336db4fee6c..0bde43c54df 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -111,7 +111,6 @@ pub fn type_allowed_to_implement_copy<'tcx>(
             // Check regions assuming the self type of the impl is WF
             let outlives_env = OutlivesEnvironment::with_bounds(
                 param_env,
-                Some(&infcx),
                 infcx.implied_bounds_tys(
                     param_env,
                     parent_cause.body_id,
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 4eacb5211f7..a5def4151bf 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -13,7 +13,6 @@ use super::{elaborate_predicates, elaborate_trait_ref};
 use crate::infer::TyCtxtInferExt;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
 use crate::traits::{self, Obligation, ObligationCause};
-use hir::def::DefKind;
 use rustc_errors::{DelayDm, FatalError, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -157,6 +156,7 @@ fn object_safety_violations_for_trait(
                 .in_definition_order()
                 .filter(|item| item.kind == ty::AssocKind::Type)
                 .filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
+                .filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
                 .map(|item| {
                     let ident = item.ident(tcx);
                     ObjectSafetyViolation::GAT(ident.name, ident.span)
@@ -854,7 +854,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
                     }
                 }
                 ty::Alias(ty::Projection, ref data)
-                    if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder =>
+                    if self.tcx.is_impl_trait_in_trait(data.def_id) =>
                 {
                     // We'll deny these later in their own pass
                     ControlFlow::Continue(())
@@ -921,7 +921,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
     ty.skip_binder().walk().find_map(|arg| {
         if let ty::GenericArgKind::Type(ty) = arg.unpack()
             && let ty::Alias(ty::Projection, proj) = ty.kind()
-            && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
+            && tcx.is_impl_trait_in_trait(proj.def_id)
         {
             Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))
         } else {
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 6cb64ad574f..e2c198fabde 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -3,7 +3,8 @@ use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
 use crate::traits::query::NoSolution;
 use crate::traits::ObligationCause;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_middle::ty::{self, ParamEnv, Ty};
+use rustc_infer::infer::resolve::OpportunisticRegionResolver;
+use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
 
 pub use rustc_middle::traits::query::OutlivesBound;
@@ -52,6 +53,10 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
         body_id: LocalDefId,
         ty: Ty<'tcx>,
     ) -> Vec<OutlivesBound<'tcx>> {
+        let ty = self.resolve_vars_if_possible(ty);
+        let ty = OpportunisticRegionResolver::new(self).fold_ty(ty);
+        assert!(!ty.needs_infer());
+
         let span = self.tcx.def_span(body_id);
         let result = param_env
             .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
@@ -105,10 +110,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
         tys: FxIndexSet<Ty<'tcx>>,
     ) -> Bounds<'a, 'tcx> {
         tys.into_iter()
-            .map(move |ty| {
-                let ty = self.resolve_vars_if_possible(ty);
-                self.implied_outlives_bounds(param_env, body_id, ty)
-            })
+            .map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty))
             .flatten()
     }
 }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 867974749d5..a2816124538 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -328,6 +328,9 @@ fn impl_associated_item_for_impl_trait_in_trait(
     // `opt_local_def_id_to_hir_id` with `None`.
     impl_assoc_ty.opt_local_def_id_to_hir_id(None);
 
+    // Copy span of the opaque.
+    impl_assoc_ty.def_ident_span(Some(span));
+
     impl_assoc_ty.associated_item(ty::AssocItem {
         name: kw::Empty,
         kind: ty::AssocKind::Type,
@@ -342,6 +345,9 @@ fn impl_associated_item_for_impl_trait_in_trait(
     // extra predicates to assume.
     impl_assoc_ty.param_env(tcx.param_env(impl_fn_def_id));
 
+    // Copy visility of the containing function.
+    impl_assoc_ty.visibility(tcx.visibility(impl_fn_def_id));
+
     // Copy impl_defaultness of the containing function.
     impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id));
 
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index e3132fcc4c4..1788f544a7f 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -156,7 +156,11 @@ fn layout_of_uncached<'tcx>(
 
             let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
 
-            let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
+            let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type()
+                // Projection eagerly bails out when the pointee references errors,
+                // fall back to structurally deducing metadata.
+                && !pointee.references_error()
+            {
                 let metadata_ty = tcx.normalize_erasing_regions(
                     param_env,
                     tcx.mk_projection(metadata_def_id, [pointee]),
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index c8ed1f365f1..d41bf603983 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -119,12 +119,9 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
 fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     // When computing the param_env of an RPITIT, copy param_env of the containing function. The
     // synthesized associated type doesn't have extra predicates to assume.
-    let def_id =
-        if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
-            fn_def_id
-        } else {
-            def_id
-        };
+    if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
+        return tcx.param_env(fn_def_id);
+    }
 
     // Compute the bounds on Self and the type parameters.
     let ty::InstantiatedPredicates { mut predicates, .. } =
diff --git a/config.example.toml b/config.example.toml
index dee0d8f254b..7ae46203f97 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -146,6 +146,9 @@ changelog-seen = 2
 # Whether to build the clang compiler.
 #clang = false
 
+# Whether to enable llvm compilation warnings.
+#enable-warnings = false
+
 # Custom CMake defines to set when building LLVM.
 #build-config = {}
 
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
index 54d0d8a8ec2..654e03d0c3c 100644
--- a/src/bootstrap/CHANGELOG.md
+++ b/src/bootstrap/CHANGELOG.md
@@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - If you have Rust already installed, `x.py` will now infer the host target
   from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513)
 - Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false.
+- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false.
 
 
 ## [Version 2] - 2020-09-25
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index fc5aa8a245d..58729f396f0 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -133,6 +133,7 @@ pub struct Config {
     pub llvm_allow_old_toolchain: bool,
     pub llvm_polly: bool,
     pub llvm_clang: bool,
+    pub llvm_enable_warnings: bool,
     pub llvm_from_ci: bool,
     pub llvm_build_config: HashMap<String, String>,
 
@@ -688,6 +689,7 @@ define_config! {
         allow_old_toolchain: Option<bool> = "allow-old-toolchain",
         polly: Option<bool> = "polly",
         clang: Option<bool> = "clang",
+        enable_warnings: Option<bool> = "enable-warnings",
         download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
         build_config: Option<HashMap<String, String>> = "build-config",
     }
@@ -1184,6 +1186,7 @@ impl Config {
             config.llvm_allow_old_toolchain = llvm.allow_old_toolchain.unwrap_or(false);
             config.llvm_polly = llvm.polly.unwrap_or(false);
             config.llvm_clang = llvm.clang.unwrap_or(false);
+            config.llvm_enable_warnings = llvm.enable_warnings.unwrap_or(false);
             config.llvm_build_config = llvm.build_config.clone().unwrap_or(Default::default());
 
             let asserts = llvm_assertions.unwrap_or(false);
diff --git a/src/bootstrap/defaults/config.codegen.toml b/src/bootstrap/defaults/config.codegen.toml
index eb2afa555f1..20b2699c761 100644
--- a/src/bootstrap/defaults/config.codegen.toml
+++ b/src/bootstrap/defaults/config.codegen.toml
@@ -7,6 +7,8 @@ compiler-docs = true
 # This enables debug-assertions in LLVM,
 # catching logic errors in codegen much earlier in the process.
 assertions = true
+# enable warnings during the llvm compilation
+enable-warnings = true
 
 [rust]
 # This enables `RUSTC_LOG=debug`, avoiding confusing situations
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 22ddf872215..f136690592d 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -495,6 +495,7 @@ impl Build {
 
         // Make a symbolic link so we can use a consistent directory in the documentation.
         let build_triple = build.out.join(&build.build.triple);
+        t!(fs::create_dir_all(&build_triple));
         let host = build.out.join("host");
         if let Err(e) = symlink_dir(&build.config, &build_triple, &host) {
             if e.kind() != ErrorKind::AlreadyExists {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 040e36ea5f8..41ee5096553 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -304,6 +304,7 @@ impl Step for Llvm {
         let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" };
         let plugins = if builder.config.llvm_plugins { "ON" } else { "OFF" };
         let enable_tests = if builder.config.llvm_tests { "ON" } else { "OFF" };
+        let enable_warnings = if builder.config.llvm_enable_warnings { "ON" } else { "OFF" };
 
         cfg.out_dir(&out_dir)
             .profile(profile)
@@ -321,7 +322,8 @@ impl Step for Llvm {
             .define("LLVM_ENABLE_Z3_SOLVER", "OFF")
             .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
             .define("LLVM_TARGET_ARCH", target_native.split('-').next().unwrap())
-            .define("LLVM_DEFAULT_TARGET_TRIPLE", target_native);
+            .define("LLVM_DEFAULT_TARGET_TRIPLE", target_native)
+            .define("LLVM_ENABLE_WARNINGS", enable_warnings);
 
         // Parts of our test suite rely on the `FileCheck` tool, which is built by default in
         // `build/$TARGET/llvm/build/bin` is but *not* then installed to `build/$TARGET/llvm/bin`.
@@ -483,11 +485,6 @@ impl Step for Llvm {
             cfg.define(key, val);
         }
 
-        // FIXME: we don't actually need to build all LLVM tools and all LLVM
-        //        libraries here, e.g., we just want a few components and a few
-        //        tools. Figure out how to filter them down and only build the right
-        //        tools and libs on all platforms.
-
         if builder.config.dry_run() {
             return res;
         }
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 9eafa27e2b7..2d74a224096 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -295,6 +295,7 @@ target | std | host | notes
 [`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? |  | RISC-V Xous (RV32IMAC ISA)
 `riscv32imc-esp-espidf` | ✓ |  | RISC-V ESP-IDF
 `riscv64gc-unknown-freebsd` |   |   | RISC-V FreeBSD
+`riscv64gc-unknown-fuchsia` |   |   | RISC-V Fuchsia
 `riscv64gc-unknown-linux-musl` |   |   | RISC-V Linux (kernel 4.20, musl 1.2.0)
 [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
 `s390x-unknown-linux-musl` |  |  | S390x Linux (kernel 3.2, MUSL)
diff --git a/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs b/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs
new file mode 100644
index 00000000000..fdbfa1b096d
--- /dev/null
+++ b/tests/codegen-units/polymorphization/auxiliary/poly-dep.rs
@@ -0,0 +1,4 @@
+// compile-flags: -Zpolymorphize=on
+
+#[inline(never)]
+pub fn foo<T>() {}
diff --git a/tests/codegen-units/polymorphization/poly-foreign.rs b/tests/codegen-units/polymorphization/poly-foreign.rs
new file mode 100644
index 00000000000..9da082daf11
--- /dev/null
+++ b/tests/codegen-units/polymorphization/poly-foreign.rs
@@ -0,0 +1,11 @@
+// aux-build:poly-dep.rs
+// compile-flags: --crate-type=lib -Zprint-mono-items=eager -Zpolymorphize=on
+
+extern crate poly_dep;
+
+pub static FN1: fn() = poly_dep::foo::<i32>;
+pub static FN2: fn() = poly_dep::foo::<u32>;
+
+//~ MONO_ITEM static FN1
+//~ MONO_ITEM static FN2
+//~ MONO_ITEM fn poly_dep::foo::<T>
diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs
index 974f5aaff83..89ca4039bce 100644
--- a/tests/ui/async-await/in-trait/async-associated-types.rs
+++ b/tests/ui/async-await/in-trait/async-associated-types.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(impl_trait_projections)]
diff --git a/tests/ui/async-await/in-trait/async-associated-types2.rs b/tests/ui/async-await/in-trait/async-associated-types2.rs
index e546a0579c6..cdecb02bfad 100644
--- a/tests/ui/async-await/in-trait/async-associated-types2.rs
+++ b/tests/ui/async-await/in-trait/async-associated-types2.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr
index 168ef8e9ee4..b5ace9ada4f 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr
@@ -1,11 +1,11 @@
 error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:15:28
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28
    |
 LL |     async fn foo(&self) -> i32 {
    |                            ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
    |
 note: type in trait
-  --> $DIR/async-example-desugared-boxed-in-trait.rs:11:22
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22
    |
 LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr
new file mode 100644
index 00000000000..b5ace9ada4f
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr
@@ -0,0 +1,17 @@
+error[E0053]: method `foo` has an incompatible type for trait
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28
+   |
+LL |     async fn foo(&self) -> i32 {
+   |                            ^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
+   |
+note: type in trait
+  --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22
+   |
+LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected signature `fn(&i32) -> Pin<Box<dyn Future<Output = i32>>>`
+              found signature `fn(&i32) -> impl Future<Output = i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
index 38ba297189c..7b53379b24b 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr
index 60fa534a64f..6c0b5859186 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr
@@ -1,5 +1,5 @@
 error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-boxed.rs:15:5
+  --> $DIR/async-example-desugared-boxed.rs:17:5
    |
 LL |     async fn foo(&self) -> i32;
    |     --------------------------- required because the trait method is async
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr
new file mode 100644
index 00000000000..6c0b5859186
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr
@@ -0,0 +1,11 @@
+error: method `foo` should be async because the method from the trait is async
+  --> $DIR/async-example-desugared-boxed.rs:17:5
+   |
+LL |     async fn foo(&self) -> i32;
+   |     --------------------------- required because the trait method is async
+...
+LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
index 1b1b3cffd58..916488ffafa 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
index 81e1e59a362..edac0b374a3 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs
index feeda719e03..934f7643dd1 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-in-trait.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr
index 567a36a86d1..0d2551ab84f 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr
+++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr
@@ -1,5 +1,5 @@
 error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-manual.rs:23:5
+  --> $DIR/async-example-desugared-manual.rs:25:5
    |
 LL |     async fn foo(&self) -> i32;
    |     --------------------------- required because the trait method is async
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr
new file mode 100644
index 00000000000..0d2551ab84f
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr
@@ -0,0 +1,11 @@
+error: method `foo` should be async because the method from the trait is async
+  --> $DIR/async-example-desugared-manual.rs:25:5
+   |
+LL |     async fn foo(&self) -> i32;
+   |     --------------------------- required because the trait method is async
+...
+LL |     fn foo(&self) -> MyFuture {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
index 71473e7455f..4883828d32f 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-example-desugared.rs b/tests/ui/async-await/in-trait/async-example-desugared.rs
index fb92ec78674..214171b2e2c 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr
index cab173bdd5b..67b491f19d2 100644
--- a/tests/ui/async-await/in-trait/async-recursive-generic.stderr
+++ b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive-generic.rs:11:48
+  --> $DIR/async-recursive-generic.rs:13:48
    |
 LL |     async fn foo_recursive(&self, n: usize) -> T {
    |                                                ^ recursive `async fn`
diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr
new file mode 100644
index 00000000000..67b491f19d2
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/async-recursive-generic.rs:13:48
+   |
+LL |     async fn foo_recursive(&self, n: usize) -> T {
+   |                                                ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.rs b/tests/ui/async-await/in-trait/async-recursive-generic.rs
index 6839abd381c..64c6ba15c0c 100644
--- a/tests/ui/async-await/in-trait/async-recursive-generic.rs
+++ b/tests/ui/async-await/in-trait/async-recursive-generic.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/async-recursive.stderr b/tests/ui/async-await/in-trait/async-recursive.current.stderr
index 9feff37b3fe..85af27e3746 100644
--- a/tests/ui/async-await/in-trait/async-recursive.stderr
+++ b/tests/ui/async-await/in-trait/async-recursive.current.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/async-recursive.rs:11:48
+  --> $DIR/async-recursive.rs:13:48
    |
 LL |     async fn foo_recursive(&self, n: usize) -> i32 {
    |                                                ^^^ recursive `async fn`
diff --git a/tests/ui/async-await/in-trait/async-recursive.next.stderr b/tests/ui/async-await/in-trait/async-recursive.next.stderr
new file mode 100644
index 00000000000..85af27e3746
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-recursive.next.stderr
@@ -0,0 +1,12 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/async-recursive.rs:13:48
+   |
+LL |     async fn foo_recursive(&self, n: usize) -> i32 {
+   |                                                ^^^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
+   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/in-trait/async-recursive.rs b/tests/ui/async-await/in-trait/async-recursive.rs
index 61119f8095b..d928909e3ae 100644
--- a/tests/ui/async-await/in-trait/async-recursive.rs
+++ b/tests/ui/async-await/in-trait/async-recursive.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/bad-signatures.stderr b/tests/ui/async-await/in-trait/bad-signatures.current.stderr
index e0ba7b53ec4..5a05b080c3e 100644
--- a/tests/ui/async-await/in-trait/bad-signatures.stderr
+++ b/tests/ui/async-await/in-trait/bad-signatures.current.stderr
@@ -1,11 +1,11 @@
 error: expected identifier, found keyword `self`
-  --> $DIR/bad-signatures.rs:7:23
+  --> $DIR/bad-signatures.rs:9:23
    |
 LL |     async fn bar(&abc self);
    |                       ^^^^ expected identifier, found keyword
 
 error: expected one of `:`, `@`, or `|`, found keyword `self`
-  --> $DIR/bad-signatures.rs:7:23
+  --> $DIR/bad-signatures.rs:9:23
    |
 LL |     async fn bar(&abc self);
    |                  -----^^^^
@@ -14,7 +14,7 @@ LL |     async fn bar(&abc self);
    |                  help: declare the type after the parameter binding: `<identifier>: <type>`
 
 warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/bad-signatures.rs:3:12
+  --> $DIR/bad-signatures.rs:5:12
    |
 LL | #![feature(async_fn_in_trait)]
    |            ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/in-trait/bad-signatures.next.stderr b/tests/ui/async-await/in-trait/bad-signatures.next.stderr
new file mode 100644
index 00000000000..5a05b080c3e
--- /dev/null
+++ b/tests/ui/async-await/in-trait/bad-signatures.next.stderr
@@ -0,0 +1,26 @@
+error: expected identifier, found keyword `self`
+  --> $DIR/bad-signatures.rs:9:23
+   |
+LL |     async fn bar(&abc self);
+   |                       ^^^^ expected identifier, found keyword
+
+error: expected one of `:`, `@`, or `|`, found keyword `self`
+  --> $DIR/bad-signatures.rs:9:23
+   |
+LL |     async fn bar(&abc self);
+   |                  -----^^^^
+   |                  |    |
+   |                  |    expected one of `:`, `@`, or `|`
+   |                  help: declare the type after the parameter binding: `<identifier>: <type>`
+
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/bad-signatures.rs:5:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/async-await/in-trait/bad-signatures.rs b/tests/ui/async-await/in-trait/bad-signatures.rs
index b86f1d1c135..e0093be8cb3 100644
--- a/tests/ui/async-await/in-trait/bad-signatures.rs
+++ b/tests/ui/async-await/in-trait/bad-signatures.rs
@@ -1,4 +1,6 @@
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 //~^ WARN the feature `async_fn_in_trait` is incomplete
diff --git a/tests/ui/async-await/in-trait/early-bound-1.rs b/tests/ui/async-await/in-trait/early-bound-1.rs
index 6b3b142014b..30843473def 100644
--- a/tests/ui/async-await/in-trait/early-bound-1.rs
+++ b/tests/ui/async-await/in-trait/early-bound-1.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/early-bound-2.rs b/tests/ui/async-await/in-trait/early-bound-2.rs
index 270443229b0..1c5a68c2a5a 100644
--- a/tests/ui/async-await/in-trait/early-bound-2.rs
+++ b/tests/ui/async-await/in-trait/early-bound-2.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr
index 37d9669c012..1a749514989 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr
+++ b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr
@@ -1,5 +1,5 @@
 error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
-  --> $DIR/fn-not-async-err2.rs:13:22
+  --> $DIR/fn-not-async-err2.rs:15:22
    |
 LL |     fn foo(&self) -> impl Future<Output = i32> {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr
new file mode 100644
index 00000000000..1a749514989
--- /dev/null
+++ b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr
@@ -0,0 +1,12 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
+  --> $DIR/fn-not-async-err2.rs:15:22
+   |
+LL |     fn foo(&self) -> impl Future<Output = i32> {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs
index 78017429f73..5fdb7296aaf 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs
+++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs
@@ -1,4 +1,6 @@
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/implied-bounds.rs b/tests/ui/async-await/in-trait/implied-bounds.rs
index 52bceb3cc5c..45ada1d84c3 100644
--- a/tests/ui/async-await/in-trait/implied-bounds.rs
+++ b/tests/ui/async-await/in-trait/implied-bounds.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition: 2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/issue-102138.rs b/tests/ui/async-await/in-trait/issue-102138.rs
index f61b34ed99e..ced30b7e4e4 100644
--- a/tests/ui/async-await/in-trait/issue-102138.rs
+++ b/tests/ui/async-await/in-trait/issue-102138.rs
@@ -1,5 +1,7 @@
 // check-pass
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/issue-102219.rs b/tests/ui/async-await/in-trait/issue-102219.rs
index 9a35f6515cb..f3fdfa3459a 100644
--- a/tests/ui/async-await/in-trait/issue-102219.rs
+++ b/tests/ui/async-await/in-trait/issue-102219.rs
@@ -1,6 +1,8 @@
 // compile-flags:--crate-type=lib
 // edition:2021
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/async-await/in-trait/object-safety.stderr b/tests/ui/async-await/in-trait/object-safety.current.stderr
index 0b318f71f39..90e049a9960 100644
--- a/tests/ui/async-await/in-trait/object-safety.stderr
+++ b/tests/ui/async-await/in-trait/object-safety.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/object-safety.rs:3:12
+  --> $DIR/object-safety.rs:5:12
    |
 LL | #![feature(async_fn_in_trait)]
    |            ^^^^^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL | #![feature(async_fn_in_trait)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:11:12
+  --> $DIR/object-safety.rs:13:12
    |
 LL |     let x: &dyn Foo = todo!();
    |            ^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:14
+  --> $DIR/object-safety.rs:9:14
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
diff --git a/tests/ui/async-await/in-trait/object-safety.next.stderr b/tests/ui/async-await/in-trait/object-safety.next.stderr
new file mode 100644
index 00000000000..90e049a9960
--- /dev/null
+++ b/tests/ui/async-await/in-trait/object-safety.next.stderr
@@ -0,0 +1,27 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/object-safety.rs:5:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:13:12
+   |
+LL |     let x: &dyn Foo = todo!();
+   |            ^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:9:14
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     async fn foo(&self);
+   |              ^^^ ...because method `foo` is `async`
+   = help: consider moving `foo` to another trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/async-await/in-trait/object-safety.rs b/tests/ui/async-await/in-trait/object-safety.rs
index a8bc35f7e0c..f67286a20a2 100644
--- a/tests/ui/async-await/in-trait/object-safety.rs
+++ b/tests/ui/async-await/in-trait/object-safety.rs
@@ -1,4 +1,6 @@
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(async_fn_in_trait)]
 //~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
diff --git a/tests/ui/codegen/mono-impossible.rs b/tests/ui/codegen/mono-impossible.rs
new file mode 100644
index 00000000000..1ea32ed2c4f
--- /dev/null
+++ b/tests/ui/codegen/mono-impossible.rs
@@ -0,0 +1,13 @@
+// compile-flags: -Clink-dead-code=on --crate-type=lib
+// build-pass
+
+// Make sure that we don't monomorphize the impossible method `<() as Visit>::visit`,
+// which does not hold under a reveal-all param env.
+
+pub trait Visit {
+    fn visit() {}
+}
+
+pub trait Array<'a> {}
+
+impl Visit for () where (): for<'a> Array<'a> {}
diff --git a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs
index 1b7ef93f41d..0c39ade721f 100644
--- a/tests/ui/fmt/auxiliary/format-string-proc-macro.rs
+++ b/tests/ui/fmt/auxiliary/format-string-proc-macro.rs
@@ -28,25 +28,41 @@ pub fn err_with_input_span(input: TokenStream) -> TokenStream {
     TokenStream::from(TokenTree::Literal(lit))
 }
 
+fn build_format(args: impl Into<TokenStream>) -> TokenStream {
+    TokenStream::from_iter([
+        TokenTree::from(Ident::new("format", Span::call_site())),
+        TokenTree::from(Punct::new('!', Spacing::Alone)),
+        TokenTree::from(Group::new(Delimiter::Parenthesis, args.into())),
+    ])
+}
 
 #[proc_macro]
 pub fn respan_to_invalid_format_literal(input: TokenStream) -> TokenStream {
     let mut s = Literal::string("{");
     s.set_span(input.into_iter().next().unwrap().span());
-    TokenStream::from_iter([
-        TokenTree::from(Ident::new("format", Span::call_site())),
-        TokenTree::from(Punct::new('!', Spacing::Alone)),
-        TokenTree::from(Group::new(Delimiter::Parenthesis, TokenTree::from(s).into())),
-    ])
+
+    build_format(TokenTree::from(s))
 }
 
 #[proc_macro]
 pub fn capture_a_with_prepended_space_preserve_span(input: TokenStream) -> TokenStream {
     let mut s = Literal::string(" {a}");
     s.set_span(input.into_iter().next().unwrap().span());
-    TokenStream::from_iter([
-        TokenTree::from(Ident::new("format", Span::call_site())),
-        TokenTree::from(Punct::new('!', Spacing::Alone)),
-        TokenTree::from(Group::new(Delimiter::Parenthesis, TokenTree::from(s).into())),
-    ])
+
+    build_format(TokenTree::from(s))
+}
+
+#[proc_macro]
+pub fn format_args_captures(_: TokenStream) -> TokenStream {
+    r#"{ let x = 5; format!("{x}") }"#.parse().unwrap()
+}
+
+#[proc_macro]
+pub fn bad_format_args_captures(_: TokenStream) -> TokenStream {
+    r#"{ let x = 5; format!(concat!("{x}")) }"#.parse().unwrap()
+}
+
+#[proc_macro]
+pub fn identity_pm(input: TokenStream) -> TokenStream {
+    input
 }
diff --git a/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs
new file mode 100644
index 00000000000..bf5c0dcb54d
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-first-literal-is-macro.rs
@@ -0,0 +1,21 @@
+// aux-build:format-string-proc-macro.rs
+
+#[macro_use]
+extern crate format_string_proc_macro;
+
+macro_rules! identity_mbe {
+    ($tt:tt) => {
+        $tt
+        //~^ ERROR there is no argument named `a`
+    };
+}
+
+fn main() {
+    let a = 0;
+
+    format!(identity_pm!("{a}"));
+    //~^ ERROR there is no argument named `a`
+    format!(identity_mbe!("{a}"));
+    format!(concat!("{a}"));
+    //~^ ERROR there is no argument named `a`
+}
diff --git a/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr b/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr
new file mode 100644
index 00000000000..4cf3afad7b8
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-first-literal-is-macro.stderr
@@ -0,0 +1,30 @@
+error: there is no argument named `a`
+  --> $DIR/format-args-capture-first-literal-is-macro.rs:16:26
+   |
+LL |     format!(identity_pm!("{a}"));
+   |                          ^^^^^
+   |
+   = note: did you intend to capture a variable `a` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+
+error: there is no argument named `a`
+  --> $DIR/format-args-capture-first-literal-is-macro.rs:8:9
+   |
+LL |         $tt
+   |         ^^^
+   |
+   = note: did you intend to capture a variable `a` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+
+error: there is no argument named `a`
+  --> $DIR/format-args-capture-first-literal-is-macro.rs:19:13
+   |
+LL |     format!(concat!("{a}"));
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: did you intend to capture a variable `a` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs
new file mode 100644
index 00000000000..f67edf5e167
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.rs
@@ -0,0 +1,8 @@
+// aux-build:format-string-proc-macro.rs
+
+extern crate format_string_proc_macro;
+
+fn main() {
+    format_string_proc_macro::bad_format_args_captures!();
+    //~^ ERROR there is no argument named `x`
+}
diff --git a/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr
new file mode 100644
index 00000000000..bb6a14d88b3
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-from-pm-first-arg-macro.stderr
@@ -0,0 +1,12 @@
+error: there is no argument named `x`
+  --> $DIR/format-args-capture-from-pm-first-arg-macro.rs:6:5
+   |
+LL |     format_string_proc_macro::bad_format_args_captures!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: did you intend to capture a variable `x` from the surrounding scope?
+   = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/fmt/format-args-capture-issue-106408.rs b/tests/ui/fmt/format-args-capture-issue-106408.rs
new file mode 100644
index 00000000000..0fd195416ee
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-issue-106408.rs
@@ -0,0 +1,10 @@
+// check-pass
+// aux-build:format-string-proc-macro.rs
+
+extern crate format_string_proc_macro;
+
+fn main() {
+    // While literal macros like `format_args!(concat!())` are not supposed to work with implicit
+    // captures, it should work if the whole invocation comes from a macro expansion (#106408).
+    format_string_proc_macro::format_args_captures!();
+}
diff --git a/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs b/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs
new file mode 100644
index 00000000000..7553fcc4e01
--- /dev/null
+++ b/tests/ui/fmt/format-args-capture-macro-hygiene-pass.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+macro_rules! format_mbe {
+    ($tt:tt) => {
+        {
+            #[allow(unused_variables)]
+            let a = 123;
+            format!($tt)
+        }
+    };
+}
+
+fn main() {
+    let a = 0;
+    assert_eq!(format_mbe!("{a}"), "0");
+}
diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs
index 5a18983a3fa..44642a10fc0 100644
--- a/tests/ui/fmt/respanned-literal-issue-106191.rs
+++ b/tests/ui/fmt/respanned-literal-issue-106191.rs
@@ -1,15 +1,10 @@
 // aux-build:format-string-proc-macro.rs
-// check-fail
-// known-bug: #106191
-// unset-rustc-env:RUST_BACKTRACE
-// had to be reverted
-// error-pattern:unexpectedly panicked
-// failure-status:101
-// dont-check-compiler-stderr
 
 extern crate format_string_proc_macro;
 
 fn main() {
     format_string_proc_macro::respan_to_invalid_format_literal!("¡");
+    //~^ ERROR invalid format string: expected `'}'` but string was terminated
     format_args!(r#concat!("¡        {"));
+    //~^ ERROR invalid format string: expected `'}'` but string was terminated
 }
diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr
index 16717f42253..73a3af65a38 100644
--- a/tests/ui/fmt/respanned-literal-issue-106191.stderr
+++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr
@@ -1,2 +1,19 @@
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  query stack during panic:
-end of query stack
+error: invalid format string: expected `'}'` but string was terminated
+  --> $DIR/respanned-literal-issue-106191.rs:6:65
+   |
+LL |     format_string_proc_macro::respan_to_invalid_format_literal!("¡");
+   |                                                                 ^^^ expected `'}'` in format string
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `'}'` but string was terminated
+  --> $DIR/respanned-literal-issue-106191.rs:8:18
+   |
+LL |     format_args!(r#concat!("¡        {"));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string
+   |
+   = note: if you intended to print `{`, you can escape it using `{{`
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/impl-trait/in-trait/deep-match-works.rs b/tests/ui/impl-trait/in-trait/deep-match-works.rs
index 772da845ee1..5c9d2e356fc 100644
--- a/tests/ui/impl-trait/in-trait/deep-match-works.rs
+++ b/tests/ui/impl-trait/in-trait/deep-match-works.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
@@ -10,7 +12,9 @@ trait Foo {
 }
 
 impl Foo for () {
-    fn bar() -> Wrapper<i32> { Wrapper(0) }
+    fn bar() -> Wrapper<i32> {
+        Wrapper(0)
+    }
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/deep-match.stderr b/tests/ui/impl-trait/in-trait/deep-match.current.stderr
index 3eba419c0a3..400db20c79c 100644
--- a/tests/ui/impl-trait/in-trait/deep-match.stderr
+++ b/tests/ui/impl-trait/in-trait/deep-match.current.stderr
@@ -1,7 +1,7 @@
 error[E0053]: method `bar` has an incompatible return type for trait
-  --> $DIR/deep-match.rs:11:17
+  --> $DIR/deep-match.rs:14:17
    |
-LL |     fn bar() -> i32 { 0 }
+LL |     fn bar() -> i32 {
    |                 ^^^
    |                 |
    |                 expected `Wrapper<_>`, found `i32`
diff --git a/tests/ui/impl-trait/in-trait/deep-match.next.stderr b/tests/ui/impl-trait/in-trait/deep-match.next.stderr
new file mode 100644
index 00000000000..400db20c79c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/deep-match.next.stderr
@@ -0,0 +1,15 @@
+error[E0053]: method `bar` has an incompatible return type for trait
+  --> $DIR/deep-match.rs:14:17
+   |
+LL |     fn bar() -> i32 {
+   |                 ^^^
+   |                 |
+   |                 expected `Wrapper<_>`, found `i32`
+   |                 return type in trait
+   |
+   = note: expected struct `Wrapper<_>`
+                found type `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/impl-trait/in-trait/deep-match.rs b/tests/ui/impl-trait/in-trait/deep-match.rs
index a6385147c3a..413d054e148 100644
--- a/tests/ui/impl-trait/in-trait/deep-match.rs
+++ b/tests/ui/impl-trait/in-trait/deep-match.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
@@ -8,8 +11,10 @@ trait Foo {
 }
 
 impl Foo for () {
-    fn bar() -> i32 { 0 }
-    //~^ ERROR method `bar` has an incompatible return type for trait
+    fn bar() -> i32 {
+        //~^ ERROR method `bar` has an incompatible return type for trait
+        0
+    }
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr
index 7c7ebcdb7e7..a0c0589b9a1 100644
--- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.stderr
+++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/default-method-binder-shifting.rs:3:12
+  --> $DIR/default-method-binder-shifting.rs:5:12
    |
 LL | #![feature(return_position_impl_trait_in_trait)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr
new file mode 100644
index 00000000000..a0c0589b9a1
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.next.stderr
@@ -0,0 +1,11 @@
+warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-method-binder-shifting.rs:5:12
+   |
+LL | #![feature(return_position_impl_trait_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs
index 5cf90c5d93c..75b0ec93984 100644
--- a/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs
+++ b/tests/ui/impl-trait/in-trait/default-method-binder-shifting.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 //~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
diff --git a/tests/ui/impl-trait/in-trait/encode.rs b/tests/ui/impl-trait/in-trait/encode.rs
index efb9f6498ba..98aaf4a6553 100644
--- a/tests/ui/impl-trait/in-trait/encode.rs
+++ b/tests/ui/impl-trait/in-trait/encode.rs
@@ -1,5 +1,7 @@
 // build-pass
 // compile-flags: --crate-type=lib
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs
index 6341f5b4284..df77372aabd 100644
--- a/tests/ui/impl-trait/in-trait/foreign.rs
+++ b/tests/ui/impl-trait/in-trait/foreign.rs
@@ -1,5 +1,7 @@
 // check-pass
 // aux-build: rpitit.rs
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 extern crate rpitit;
 
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr
index 18bb63745d7..7aa7880e258 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.stderr
+++ b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:23:22
+  --> $DIR/issue-102140.rs:26:22
    |
 LL |         MyTrait::foo(&self)
    |         ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
@@ -13,7 +13,7 @@ LL +         MyTrait::foo(self)
    |
 
 error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:23:9
+  --> $DIR/issue-102140.rs:26:9
    |
 LL |         MyTrait::foo(&self)
    |         ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
@@ -21,7 +21,7 @@ LL |         MyTrait::foo(&self)
    = help: the trait `MyTrait` is implemented for `Outer`
 
 error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
-  --> $DIR/issue-102140.rs:23:9
+  --> $DIR/issue-102140.rs:26:9
    |
 LL |         MyTrait::foo(&self)
    |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr
new file mode 100644
index 00000000000..7aa7880e258
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:26:22
+   |
+LL |         MyTrait::foo(&self)
+   |         ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |         |
+   |         required by a bound introduced by this call
+   |
+help: consider removing the leading `&`-reference
+   |
+LL -         MyTrait::foo(&self)
+LL +         MyTrait::foo(self)
+   |
+
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:26:9
+   |
+LL |         MyTrait::foo(&self)
+   |         ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |
+   = help: the trait `MyTrait` is implemented for `Outer`
+
+error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
+  --> $DIR/issue-102140.rs:26:9
+   |
+LL |         MyTrait::foo(&self)
+   |         ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
+   |
+   = help: the trait `MyTrait` is implemented for `Outer`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.rs b/tests/ui/impl-trait/in-trait/issue-102140.rs
index be1e012acb1..4dcac4f5b0e 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.rs
+++ b/tests/ui/impl-trait/in-trait/issue-102140.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs
deleted file mode 100644
index ae09d20f6f5..00000000000
--- a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-impl-trait.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// check-pass
-// compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
-
-#![feature(return_position_impl_trait_in_trait)]
-#![allow(incomplete_features)]
-
-trait Foo {
-    fn foo() -> impl Sized;
-}
-
-impl Foo for String {
-    fn foo() -> i32 {
-        22
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs
deleted file mode 100644
index dfce973d770..00000000000
--- a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// check-pass
-// compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
-
-#![feature(return_position_impl_trait_in_trait)]
-#![allow(incomplete_features)]
-
-trait Foo {
-    fn foo() -> impl Sized;
-}
-
-fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr
index ca0e760ff6d..b7f2b019a77 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr
@@ -1,11 +1,11 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:17:33
+  --> $DIR/object-safety.rs:20:33
    |
 LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |                                 ^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:22
+  --> $DIR/object-safety.rs:10:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
@@ -14,13 +14,13 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:20:13
+  --> $DIR/object-safety.rs:23:13
    |
 LL |     let s = i.baz();
    |             ^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:22
+  --> $DIR/object-safety.rs:10:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
@@ -29,13 +29,13 @@ LL |     fn baz(&self) -> impl Debug;
    = help: consider moving `baz` to another trait
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/object-safety.rs:17:13
+  --> $DIR/object-safety.rs:20:13
    |
 LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
    |             ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
    |
 note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/object-safety.rs:7:22
+  --> $DIR/object-safety.rs:10:22
    |
 LL | trait Foo {
    |       --- this trait cannot be made into an object...
diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr
new file mode 100644
index 00000000000..b7f2b019a77
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr
@@ -0,0 +1,50 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:20:33
+   |
+LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
+   |                                 ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:10:22
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> impl Debug;
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+   = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:23:13
+   |
+LL |     let s = i.baz();
+   |             ^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:10:22
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> impl Debug;
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+   = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety.rs:20:13
+   |
+LL |     let i = Box::new(42_u32) as Box<dyn Foo>;
+   |             ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/object-safety.rs:10:22
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     fn baz(&self) -> impl Debug;
+   |                      ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+   = help: consider moving `baz` to another trait
+   = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
+   = note: required by cast to type `Box<dyn Foo>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs
index dd35b9a2d8a..016a0aaae4b 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.rs
+++ b/tests/ui/impl-trait/in-trait/object-safety.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr
index 15edda48340..a57653b2c9e 100644
--- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr
+++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/opaque-in-impl-is-opaque.rs:17:19
+  --> $DIR/opaque-in-impl-is-opaque.rs:20:19
    |
 LL |     fn bar(&self) -> impl Display {
    |                      ------------ the found opaque type
diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr
new file mode 100644
index 00000000000..a57653b2c9e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/opaque-in-impl-is-opaque.rs:20:19
+   |
+LL |     fn bar(&self) -> impl Display {
+   |                      ------------ the found opaque type
+...
+LL |     let x: &str = ().bar();
+   |            ----   ^^^^^^^^ expected `&str`, found opaque type
+   |            |
+   |            expected due to this
+   |
+   = note: expected reference `&str`
+            found opaque type `impl std::fmt::Display`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
index 3ac264e8eba..c07ece15a83 100644
--- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
+++ b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs
@@ -1,3 +1,6 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/impl-trait/in-trait/reveal.rs b/tests/ui/impl-trait/in-trait/reveal.rs
index d6ede1cc495..1f42ec744db 100644
--- a/tests/ui/impl-trait/in-trait/reveal.rs
+++ b/tests/ui/impl-trait/in-trait/reveal.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr
index c4fcaabe446..eba270af7f0 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr
@@ -1,5 +1,5 @@
 error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/signature-mismatch.rs:15:5
+  --> $DIR/signature-mismatch.rs:17:5
    |
 LL |     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
    |     ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '3`
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr
new file mode 100644
index 00000000000..eba270af7f0
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr
@@ -0,0 +1,16 @@
+error: `impl` item signature doesn't match `trait` item signature
+  --> $DIR/signature-mismatch.rs:17:5
+   |
+LL |     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
+   |     ----------------------------------------------------------------- expected `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '3`
+...
+LL |     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '2`
+   |
+   = note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '3`
+              found signature `fn(&'1 Struct, &'2 [u8]) -> impl Future<Output = Vec<u8>> + '2`
+   = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
+   = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
+
+error: aborting due to previous error
+
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
index 90682631aa0..38c902a97a9 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
@@ -1,4 +1,6 @@
 // edition:2021
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
index c9ee877db8e..dbc5d38f192 100644
--- a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
+++ b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(specialization)]
 #![feature(return_position_impl_trait_in_trait)]
diff --git a/tests/ui/impl-trait/in-trait/success.rs b/tests/ui/impl-trait/in-trait/success.rs
index 4cbe682b46f..0e69e0490c7 100644
--- a/tests/ui/impl-trait/in-trait/success.rs
+++ b/tests/ui/impl-trait/in-trait/success.rs
@@ -1,4 +1,6 @@
 // check-pass
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
 
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/implied-bounds/normalization.rs b/tests/ui/implied-bounds/normalization.rs
new file mode 100644
index 00000000000..f776fc98a9e
--- /dev/null
+++ b/tests/ui/implied-bounds/normalization.rs
@@ -0,0 +1,58 @@
+// Test that we get implied bounds from complex projections after normalization.
+
+// check-pass
+
+// implementations wil ensure that
+// WF(<T as Combine<'a>>::Ty) implies T: 'a
+trait Combine<'a> {
+    type Ty;
+}
+
+impl<'a, T: 'a> Combine<'a> for Box<T> {
+    type Ty = &'a T;
+}
+
+// ======= Wrappers ======
+
+// normalizes to a projection
+struct WrapA<T>(T);
+impl<'a, T> Combine<'a> for WrapA<T>
+where
+    T: Combine<'a>,
+{
+    type Ty = T::Ty;
+}
+
+// <WrapB<T> as Combine<'a>>::Ty normalizes to a type variable ?X
+// with constraint `<T as Combine<'a>>::Ty == ?X`
+struct WrapB<T>(T);
+impl<'a, X, T> Combine<'a> for WrapB<T>
+where
+    T: Combine<'a, Ty = X>,
+{
+    type Ty = X;
+}
+
+// <WrapC<T> as Combine<'a>>::Ty normalizes to `&'a &'?x ()`
+// with constraint `<T as Combine<'a>>::Ty == &'a &'?x ()`
+struct WrapC<T>(T);
+impl<'a, 'x: 'a, T> Combine<'a> for WrapC<T>
+where
+    T: Combine<'a, Ty = &'a &'x ()>,
+{
+    type Ty = &'a &'x ();
+}
+
+//==== Test implied bounds ======
+
+fn test_wrap<'a, 'b, 'c1, 'c2, A, B>(
+    _: <WrapA<Box<A>> as Combine<'a>>::Ty,        // normalized: &'a A
+    _: <WrapB<Box<B>> as Combine<'b>>::Ty,        // normalized: &'b B
+    _: <WrapC<Box<&'c1 ()>> as Combine<'c2>>::Ty, // normalized: &'c2 &'c1 ()
+) {
+    None::<&'a A>;
+    None::<&'b B>;
+    None::<&'c2 &'c1 ()>;
+}
+
+fn main() {}
diff --git a/tests/ui/layout/transmute-to-tail-with-err.rs b/tests/ui/layout/transmute-to-tail-with-err.rs
new file mode 100644
index 00000000000..6753ce15ed1
--- /dev/null
+++ b/tests/ui/layout/transmute-to-tail-with-err.rs
@@ -0,0 +1,8 @@
+trait Trait<T> {}
+
+struct Bar(Box<dyn Trait<T>>);
+//~^ ERROR cannot find type `T` in this scope
+
+fn main() {
+    let x: Bar = unsafe { std::mem::transmute(()) };
+}
diff --git a/tests/ui/layout/transmute-to-tail-with-err.stderr b/tests/ui/layout/transmute-to-tail-with-err.stderr
new file mode 100644
index 00000000000..97ab59c398a
--- /dev/null
+++ b/tests/ui/layout/transmute-to-tail-with-err.stderr
@@ -0,0 +1,14 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/transmute-to-tail-with-err.rs:3:26
+   |
+LL | struct Bar(Box<dyn Trait<T>>);
+   |                          ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | struct Bar<T>(Box<dyn Trait<T>>);
+   |           +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/suggestions/chain-method-call-mutation-in-place.rs b/tests/ui/suggestions/chain-method-call-mutation-in-place.rs
index cb92ab87a8f..7a4c747961c 100644
--- a/tests/ui/suggestions/chain-method-call-mutation-in-place.rs
+++ b/tests/ui/suggestions/chain-method-call-mutation-in-place.rs
@@ -1,4 +1,8 @@
-fn main() {}
+fn main() {
+    let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i); //~ ERROR mismatched types
+    vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort(); //~ ERROR no method named `sort` found for unit type `()` in the current scope
+}
+
 fn foo(mut s: String) -> String {
     s.push_str("asdf") //~ ERROR mismatched types
 }
diff --git a/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr b/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr
index 11d9b8391f6..128160f10ad 100644
--- a/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr
+++ b/tests/ui/suggestions/chain-method-call-mutation-in-place.stderr
@@ -1,5 +1,33 @@
 error[E0308]: mismatched types
-  --> $DIR/chain-method-call-mutation-in-place.rs:3:5
+  --> $DIR/chain-method-call-mutation-in-place.rs:2:23
+   |
+LL |     let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
+   |            --------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec<i32>`, found `()`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `Vec<i32>`
+           found unit type `()`
+note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains.
+  --> $DIR/chain-method-call-mutation-in-place.rs:2:71
+   |
+LL |     let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
+   |                                                                       ^^^^^^^^^^^ this call modifies its receiver in-place
+
+error[E0599]: no method named `sort` found for unit type `()` in the current scope
+  --> $DIR/chain-method-call-mutation-in-place.rs:3:72
+   |
+LL |     vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
+   |                                                                        ^^^^ method not found in `()`
+   |
+note: method `sort_by_key` modifies its receiver in-place, it is not meant to be used in method chains.
+  --> $DIR/chain-method-call-mutation-in-place.rs:3:53
+   |
+LL |     vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
+   |                                                     ^^^^^^^^^^^ this call modifies its receiver in-place
+
+error[E0308]: mismatched types
+  --> $DIR/chain-method-call-mutation-in-place.rs:7:5
    |
 LL | fn foo(mut s: String) -> String {
    |                          ------ expected `String` because of return type
@@ -7,7 +35,7 @@ LL |     s.push_str("asdf")
    |     ^^^^^^^^^^^^^^^^^^ expected `String`, found `()`
    |
 note: method `push_str` modifies its receiver in-place
-  --> $DIR/chain-method-call-mutation-in-place.rs:3:7
+  --> $DIR/chain-method-call-mutation-in-place.rs:7:7
    |
 LL |     s.push_str("asdf")
    |     - ^^^^^^^^ this call modifies `s` in-place
@@ -15,6 +43,7 @@ LL |     s.push_str("asdf")
    |     you probably want to use this value after calling the method...
    = note: ...instead of the `()` output of method `push_str`
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0599.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs
new file mode 100644
index 00000000000..91c6dfb8e0a
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs
@@ -0,0 +1,11 @@
+#![feature(non_lifetime_binders)]
+//~^ WARN the feature `non_lifetime_binders` is incomplete
+
+fn b()
+where
+    for<const C: usize> [(); C]: Copy,
+    //~^ ERROR cannot capture late-bound const parameter in a constant
+{
+}
+
+fn main() {}
diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr
new file mode 100644
index 00000000000..69bb605bf41
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr
@@ -0,0 +1,19 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/capture-late-ct-in-anon.rs:1:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: cannot capture late-bound const parameter in a constant
+  --> $DIR/capture-late-ct-in-anon.rs:6:30
+   |
+LL |     for<const C: usize> [(); C]: Copy,
+   |         --------------       ^
+   |         |
+   |         parameter defined here
+
+error: aborting due to previous error; 1 warning emitted
+