about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs68
-rw-r--r--compiler/rustc_span/src/hygiene.rs2
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs10
-rw-r--r--library/core/src/slice/iter.rs4
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--src/bootstrap/bootstrap_test.py39
-rwxr-xr-xsrc/bootstrap/configure.py417
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile5
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile4
-rw-r--r--src/librustdoc/clean/mod.rs14
-rw-r--r--src/tools/rustbook/Cargo.toml2
-rw-r--r--tests/rustdoc-ui/intra-doc/import-inline-merge.rs16
-rw-r--r--tests/ui/async-await/in-trait/issue-102310.rs2
-rw-r--r--tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr (renamed from tests/ui/async-await/in-trait/lifetime-mismatch.stderr)4
-rw-r--r--tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr21
-rw-r--r--tests/ui/async-await/in-trait/lifetime-mismatch.rs2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs11
-rw-r--r--tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr18
-rw-r--r--tests/ui/impl-trait/in-trait/early.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102301.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-in-impl.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr (renamed from tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr)2
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr12
-rw-r--r--tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/where-clause.rs2
-rw-r--r--tests/ui/rfc-2091-track-caller/intrinsic-wrapper.rs5
-rw-r--r--tests/ui/rfc-2091-track-caller/mir-inlined-macro.rs23
32 files changed, 460 insertions, 260 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 23a9f2bd2b7..61f2cfb9e22 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3103,9 +3103,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.25"
+version = "0.4.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1ed28d5903dde77bd5182645078a37ee57014cac6ccb2d54e1d6496386648e4"
+checksum = "764dcbfc2e5f868bc1b566eb179dff1a06458fd0cff846aae2579392dd3f01a0"
 dependencies = [
  "ammonia",
  "anyhow",
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index f9aa2aecf65..bdfc0aa1c30 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1475,7 +1475,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) -> OperandRef<'tcx, Bx::Value> {
         let tcx = bx.tcx();
 
-        let mut span_to_caller_location = |span: Span| {
+        let mut span_to_caller_location = |mut span: Span| {
+            // Remove `Inlined` marks as they pollute `expansion_cause`.
+            while span.is_inlined() {
+                span.remove_mark();
+            }
             let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
             let caller = tcx.sess.source_map().lookup_char_pos(topmost.lo());
             let const_loc = tcx.const_caller_location((
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
index cf52299b7ba..76c8d0a975a 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs
@@ -111,7 +111,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         location
     }
 
-    pub(crate) fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
+    pub(crate) fn location_triple_for_span(&self, mut span: Span) -> (Symbol, u32, u32) {
+        // Remove `Inlined` marks as they pollute `expansion_cause`.
+        while span.is_inlined() {
+            span.remove_mark();
+        }
         let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
         let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
         (
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 71b54e11cc0..6a27383121d 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -3152,8 +3152,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         debug!("impl_trait_ty_to_ty: generics={:?}", generics);
         let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
-            if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
-                // Our own parameters are the resolved lifetimes.
+            // We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
+            // since return-position impl trait in trait squashes all of the generics from its source fn
+            // into its own generics, so the opaque's "own" params isn't always just lifetimes.
+            if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
+            {
+                // Resolve our own lifetime parameters.
                 let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
                 let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
                 self.ast_region_to_region(lifetime, None).into()
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index fe44fabf57d..4bbea878904 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -278,8 +278,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
             }
             TraitItemKind::Const(ty, body_id) => body_id
                 .and_then(|body_id| {
-                    is_suggestable_infer_ty(ty)
-                        .then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",))
+                    is_suggestable_infer_ty(ty).then(|| {
+                        infer_placeholder_type(
+                            tcx, def_id, body_id, ty.span, item.ident, "constant",
+                        )
+                    })
                 })
                 .unwrap_or_else(|| icx.to_ty(ty)),
             TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty),
@@ -335,14 +338,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                     }
                 }
                 ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
-                ItemKind::Impl(hir::Impl { self_ty, .. }) => {
-                    match self_ty.find_self_aliases() {
-                        spans if spans.len() > 0 => {
-                            let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
-                            tcx.ty_error(guar)
-                        },
-                        _ => icx.to_ty(*self_ty),
+                ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
+                    spans if spans.len() > 0 => {
+                        let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf {
+                            span: spans.into(),
+                            note: (),
+                        });
+                        tcx.ty_error(guar)
                     }
+                    _ => icx.to_ty(*self_ty),
                 },
                 ItemKind::Fn(..) => {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
@@ -364,7 +368,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                     ..
                 }) => {
                     if in_trait && !tcx.impl_defaultness(owner).has_value() {
-                        span_bug!(tcx.def_span(def_id), "tried to get type of this RPITIT with no definition");
+                        span_bug!(
+                            tcx.def_span(def_id),
+                            "tried to get type of this RPITIT with no definition"
+                        );
                     }
                     find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
                 }
@@ -453,15 +460,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                     tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
                 }
 
-                Node::TypeBinding(
-                    TypeBinding {
-                        hir_id: binding_id,
-                        kind: TypeBindingKind::Equality { term: Term::Const(e) },
-                        ident,
-                        ..
-                    },
-                ) if let Node::TraitRef(trait_ref) =
-                    tcx.hir().get_parent(*binding_id)
+                Node::TypeBinding(TypeBinding {
+                    hir_id: binding_id,
+                    kind: TypeBindingKind::Equality { term: Term::Const(e) },
+                    ident,
+                    ..
+                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
                     && e.hir_id == hir_id =>
                 {
                     let Some(trait_def_id) = trait_ref.trait_def_id() else {
@@ -475,7 +479,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                         def_id.to_def_id(),
                     );
                     if let Some(assoc_item) = assoc_item {
-                        tcx.type_of(assoc_item.def_id).subst_identity()
+                        tcx.type_of(assoc_item.def_id)
+                            .no_bound_vars()
+                            .expect("const parameter types cannot be generic")
                     } else {
                         // FIXME(associated_const_equality): add a useful error message here.
                         tcx.ty_error_with_message(
@@ -485,10 +491,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                     }
                 }
 
-                Node::TypeBinding(
-                    TypeBinding { hir_id: binding_id, gen_args, kind, ident, .. },
-                ) if let Node::TraitRef(trait_ref) =
-                    tcx.hir().get_parent(*binding_id)
+                Node::TypeBinding(TypeBinding {
+                    hir_id: binding_id,
+                    gen_args,
+                    kind,
+                    ident,
+                    ..
+                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
                     && let Some((idx, _)) =
                         gen_args.args.iter().enumerate().find(|(_, arg)| {
                             if let GenericArg::Const(ct) = arg {
@@ -517,15 +526,18 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
                         },
                         def_id.to_def_id(),
                     );
-                    if let Some(param)
-                        = assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const())
+                    if let Some(assoc_item) = assoc_item
+                        && let param = &tcx.generics_of(assoc_item.def_id).params[idx]
+                        && matches!(param.kind, ty::GenericParamDefKind::Const { .. })
                     {
-                        tcx.type_of(param.def_id).subst_identity()
+                        tcx.type_of(param.def_id)
+                            .no_bound_vars()
+                            .expect("const parameter types cannot be generic")
                     } else {
                         // FIXME(associated_const_equality): add a useful error message here.
                         tcx.ty_error_with_message(
                             DUMMY_SP,
-                            "Could not find associated const on trait",
+                            "Could not find const param on associated item",
                         )
                     }
                 }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 9f22e9776d4..d727aba6de5 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -880,7 +880,7 @@ impl Span {
     pub fn fresh_expansion(self, expn_id: LocalExpnId) -> Span {
         HygieneData::with(|data| {
             self.with_ctxt(data.apply_mark(
-                SyntaxContext::root(),
+                self.ctxt(),
                 expn_id.to_expn_id(),
                 Transparency::Transparent,
             ))
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index b5bd6a81ff8..87fdaa14f6b 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -396,6 +396,8 @@ fn associated_type_for_impl_trait_in_impl(
     impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id));
 
     // Copy generics_of the trait's associated item but the impl as the parent.
+    // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl
+    // generics.
     impl_assoc_ty.generics_of({
         let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
         let trait_assoc_parent_count = trait_assoc_generics.parent_count;
@@ -404,16 +406,10 @@ fn associated_type_for_impl_trait_in_impl(
         let parent_generics = tcx.generics_of(impl_def_id);
         let parent_count = parent_generics.parent_count + parent_generics.params.len();
 
-        let mut impl_fn_params = tcx.generics_of(impl_fn_def_id).params.clone();
-
         for param in &mut params {
-            param.index = param.index + parent_count as u32 + impl_fn_params.len() as u32
-                - trait_assoc_parent_count as u32;
+            param.index = param.index + parent_count as u32 - trait_assoc_parent_count as u32;
         }
 
-        impl_fn_params.extend(params);
-        params = impl_fn_params;
-
         let param_def_id_to_index =
             params.iter().map(|param| (param.def_id, param.index)).collect();
 
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index c4317799bcc..88b84bd1352 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -132,9 +132,7 @@ iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, {
         Self: Sized,
         F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
     {
-        self.as_slice().windows(2).all(|w| {
-            compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false)
-        })
+        self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
     }
 }}
 
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index d319b2bc37f..57b6e0ce4bb 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3822,7 +3822,7 @@ impl<T> [T] {
     where
         F: FnMut(&'a T, &'a T) -> Option<Ordering>,
     {
-        self.iter().is_sorted_by(|a, b| compare(*a, *b))
+        self.array_windows().all(|[a, b]| compare(a, b).map_or(false, Ordering::is_le))
     }
 
     /// Checks if the elements of this slice are sorted using the given key extraction function.
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index 06ca3ce21b3..20bd71f06e9 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -11,6 +11,7 @@ import sys
 from shutil import rmtree
 
 import bootstrap
+import configure
 
 
 class VerifyTestCase(unittest.TestCase):
@@ -74,12 +75,50 @@ class ProgramOutOfDate(unittest.TestCase):
         self.assertFalse(self.build.program_out_of_date(self.rustc_stamp_path, self.key))
 
 
+class GenerateAndParseConfig(unittest.TestCase):
+    """Test that we can serialize and deserialize a config.toml file"""
+    def serialize_and_parse(self, args):
+        from io import StringIO
+
+        section_order, sections, targets = configure.parse_args(args)
+        buffer = StringIO()
+        configure.write_config_toml(buffer, section_order, targets, sections)
+        build = bootstrap.RustBuild()
+        build.config_toml = buffer.getvalue()
+
+        try:
+            import tomllib
+            # Verify this is actually valid TOML.
+            tomllib.loads(build.config_toml)
+        except ImportError:
+            print("warning: skipping TOML validation, need at least python 3.11", file=sys.stderr)
+        return build
+
+    def test_no_args(self):
+        build = self.serialize_and_parse([])
+        self.assertEqual(build.get_toml("changelog-seen"), '2')
+        self.assertIsNone(build.get_toml("llvm.download-ci-llvm"))
+
+    def test_set_section(self):
+        build = self.serialize_and_parse(["--set", "llvm.download-ci-llvm"])
+        self.assertEqual(build.get_toml("download-ci-llvm", section="llvm"), 'true')
+
+    def test_set_target(self):
+        build = self.serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"])
+        self.assertEqual(build.get_toml("cc", section="target.x86_64-unknown-linux-gnu"), 'gcc')
+
+    # Uncomment when #108928 is fixed.
+    # def test_set_top_level(self):
+    #     build = self.serialize_and_parse(["--set", "profile=compiler"])
+    #     self.assertEqual(build.get_toml("profile"), 'compiler')
+
 if __name__ == '__main__':
     SUITE = unittest.TestSuite()
     TEST_LOADER = unittest.TestLoader()
     SUITE.addTest(doctest.DocTestSuite(bootstrap))
     SUITE.addTests([
         TEST_LOADER.loadTestsFromTestCase(VerifyTestCase),
+        TEST_LOADER.loadTestsFromTestCase(GenerateAndParseConfig),
         TEST_LOADER.loadTestsFromTestCase(ProgramOutOfDate)])
 
     RUNNER = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index b326ae402aa..abd28b4005d 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -205,77 +205,78 @@ if '--help' in sys.argv or '-h' in sys.argv:
 
 # Parse all command line arguments into one of these three lists, handling
 # boolean and value-based options separately
-unknown_args = []
-need_value_args = []
-known_args = {}
-
-p("processing command line")
-i = 1
-while i < len(sys.argv):
-    arg = sys.argv[i]
-    i += 1
-    if not arg.startswith('--'):
-        unknown_args.append(arg)
-        continue
-
-    found = False
-    for option in options:
-        value = None
-        if option.value:
-            keyval = arg[2:].split('=', 1)
-            key = keyval[0]
-            if option.name != key:
-                continue
+def parse_args(args):
+    unknown_args = []
+    need_value_args = []
+    known_args = {}
+
+    i = 0
+    while i < len(args):
+        arg = args[i]
+        i += 1
+        if not arg.startswith('--'):
+            unknown_args.append(arg)
+            continue
 
-            if len(keyval) > 1:
-                value = keyval[1]
-            elif i < len(sys.argv):
-                value = sys.argv[i]
-                i += 1
-            else:
-                need_value_args.append(arg)
-                continue
-        else:
-            if arg[2:] == 'enable-' + option.name:
-                value = True
-            elif arg[2:] == 'disable-' + option.name:
-                value = False
+        found = False
+        for option in options:
+            value = None
+            if option.value:
+                keyval = arg[2:].split('=', 1)
+                key = keyval[0]
+                if option.name != key:
+                    continue
+
+                if len(keyval) > 1:
+                    value = keyval[1]
+                elif i < len(args):
+                    value = args[i]
+                    i += 1
+                else:
+                    need_value_args.append(arg)
+                    continue
             else:
-                continue
+                if arg[2:] == 'enable-' + option.name:
+                    value = True
+                elif arg[2:] == 'disable-' + option.name:
+                    value = False
+                else:
+                    continue
+
+            found = True
+            if option.name not in known_args:
+                known_args[option.name] = []
+            known_args[option.name].append((option, value))
+            break
+
+        if not found:
+            unknown_args.append(arg)
+
+    # Note: here and a few other places, we use [-1] to apply the *last* value
+    # passed.  But if option-checking is enabled, then the known_args loop will
+    # also assert that options are only passed once.
+    option_checking = ('option-checking' not in known_args
+                    or known_args['option-checking'][-1][1])
+    if option_checking:
+        if len(unknown_args) > 0:
+            err("Option '" + unknown_args[0] + "' is not recognized")
+        if len(need_value_args) > 0:
+            err("Option '{0}' needs a value ({0}=val)".format(need_value_args[0]))
+
+    config = {}
+
+    set('build.configure-args', sys.argv[1:], config)
+    apply_args(known_args, option_checking, config)
+    return parse_example_config(known_args, config)
 
-        found = True
-        if option.name not in known_args:
-            known_args[option.name] = []
-        known_args[option.name].append((option, value))
-        break
-
-    if not found:
-        unknown_args.append(arg)
-p("")
-
-# Note: here and a few other places, we use [-1] to apply the *last* value
-# passed.  But if option-checking is enabled, then the known_args loop will
-# also assert that options are only passed once.
-option_checking = ('option-checking' not in known_args
-                   or known_args['option-checking'][-1][1])
-if option_checking:
-    if len(unknown_args) > 0:
-        err("Option '" + unknown_args[0] + "' is not recognized")
-    if len(need_value_args) > 0:
-        err("Option '{0}' needs a value ({0}=val)".format(need_value_args[0]))
-
-# Parse all known arguments into a configuration structure that reflects the
-# TOML we're going to write out
-config = {}
-
-
-def build():
+
+def build(known_args):
     if 'build' in known_args:
         return known_args['build'][-1][1]
     return bootstrap.default_build_triple(verbose=False)
 
 
-def set(key, value):
+def set(key, value, config):
     if isinstance(value, list):
         # Remove empty values, which value.split(',') tends to generate.
         value = [v for v in value if v]
@@ -297,75 +298,76 @@ def set(key, value):
             arr = arr[part]
 
 
-for key in known_args:
-    # The `set` option is special and can be passed a bunch of times
-    if key == 'set':
-        for option, value in known_args[key]:
-            keyval = value.split('=', 1)
-            if len(keyval) == 1 or keyval[1] == "true":
-                value = True
-            elif keyval[1] == "false":
-                value = False
-            else:
-                value = keyval[1]
-            set(keyval[0], value)
-        continue
-
-    # Ensure each option is only passed once
-    arr = known_args[key]
-    if option_checking and len(arr) > 1:
-        err("Option '{}' provided more than once".format(key))
-    option, value = arr[-1]
-
-    # If we have a clear avenue to set our value in rustbuild, do so
-    if option.rustbuild is not None:
-        set(option.rustbuild, value)
-        continue
-
-    # Otherwise we're a "special" option and need some extra handling, so do
-    # that here.
-    if option.name == 'sccache':
-        set('llvm.ccache', 'sccache')
-    elif option.name == 'local-rust':
-        for path in os.environ['PATH'].split(os.pathsep):
-            if os.path.exists(path + '/rustc'):
-                set('build.rustc', path + '/rustc')
-                break
-        for path in os.environ['PATH'].split(os.pathsep):
-            if os.path.exists(path + '/cargo'):
-                set('build.cargo', path + '/cargo')
-                break
-    elif option.name == 'local-rust-root':
-        set('build.rustc', value + '/bin/rustc')
-        set('build.cargo', value + '/bin/cargo')
-    elif option.name == 'llvm-root':
-        set('target.{}.llvm-config'.format(build()), value + '/bin/llvm-config')
-    elif option.name == 'llvm-config':
-        set('target.{}.llvm-config'.format(build()), value)
-    elif option.name == 'llvm-filecheck':
-        set('target.{}.llvm-filecheck'.format(build()), value)
-    elif option.name == 'tools':
-        set('build.tools', value.split(','))
-    elif option.name == 'codegen-backends':
-        set('rust.codegen-backends', value.split(','))
-    elif option.name == 'host':
-        set('build.host', value.split(','))
-    elif option.name == 'target':
-        set('build.target', value.split(','))
-    elif option.name == 'full-tools':
-        set('rust.codegen-backends', ['llvm'])
-        set('rust.lld', True)
-        set('rust.llvm-tools', True)
-        set('build.extended', True)
-    elif option.name == 'option-checking':
-        # this was handled above
-        pass
-    elif option.name == 'dist-compression-formats':
-        set('dist.compression-formats', value.split(','))
-    else:
-        raise RuntimeError("unhandled option {}".format(option.name))
+def apply_args(known_args, option_checking, config):
+    for key in known_args:
+        # The `set` option is special and can be passed a bunch of times
+        if key == 'set':
+            for option, value in known_args[key]:
+                keyval = value.split('=', 1)
+                if len(keyval) == 1 or keyval[1] == "true":
+                    value = True
+                elif keyval[1] == "false":
+                    value = False
+                else:
+                    value = keyval[1]
+                set(keyval[0], value, config)
+            continue
 
-set('build.configure-args', sys.argv[1:])
+        # Ensure each option is only passed once
+        arr = known_args[key]
+        if option_checking and len(arr) > 1:
+            err("Option '{}' provided more than once".format(key))
+        option, value = arr[-1]
+
+        # If we have a clear avenue to set our value in rustbuild, do so
+        if option.rustbuild is not None:
+            set(option.rustbuild, value, config)
+            continue
+
+        # Otherwise we're a "special" option and need some extra handling, so do
+        # that here.
+        build_triple = build(known_args)
+
+        if option.name == 'sccache':
+            set('llvm.ccache', 'sccache', config)
+        elif option.name == 'local-rust':
+            for path in os.environ['PATH'].split(os.pathsep):
+                if os.path.exists(path + '/rustc'):
+                    set('build.rustc', path + '/rustc', config)
+                    break
+            for path in os.environ['PATH'].split(os.pathsep):
+                if os.path.exists(path + '/cargo'):
+                    set('build.cargo', path + '/cargo', config)
+                    break
+        elif option.name == 'local-rust-root':
+            set('build.rustc', value + '/bin/rustc', config)
+            set('build.cargo', value + '/bin/cargo', config)
+        elif option.name == 'llvm-root':
+            set('target.{}.llvm-config'.format(build_triple), value + '/bin/llvm-config', config)
+        elif option.name == 'llvm-config':
+            set('target.{}.llvm-config'.format(build_triple), value, config)
+        elif option.name == 'llvm-filecheck':
+            set('target.{}.llvm-filecheck'.format(build_triple), value, config)
+        elif option.name == 'tools':
+            set('build.tools', value.split(','), config)
+        elif option.name == 'codegen-backends':
+            set('rust.codegen-backends', value.split(','), config)
+        elif option.name == 'host':
+            set('build.host', value.split(','), config)
+        elif option.name == 'target':
+            set('build.target', value.split(','), config)
+        elif option.name == 'full-tools':
+            set('rust.codegen-backends', ['llvm'], config)
+            set('rust.lld', True, config)
+            set('rust.llvm-tools', True, config)
+            set('build.extended', True, config)
+        elif option.name == 'option-checking':
+            # this was handled above
+            pass
+        elif option.name == 'dist-compression-formats':
+            set('dist.compression-formats', value.split(','), config)
+        else:
+            raise RuntimeError("unhandled option {}".format(option.name))
 
 # "Parse" the `config.example.toml` file into the various sections, and we'll
 # use this as a template of a `config.toml` to write out which preserves
@@ -373,46 +375,50 @@ set('build.configure-args', sys.argv[1:])
 #
 # Note that the `target` section is handled separately as we'll duplicate it
 # per configured target, so there's a bit of special handling for that here.
-sections = {}
-cur_section = None
-sections[None] = []
-section_order = [None]
-targets = {}
-top_level_keys = []
-
-for line in open(rust_dir + '/config.example.toml').read().split("\n"):
-    if cur_section == None:
-        if line.count('=') == 1:
-            top_level_key = line.split('=')[0]
-            top_level_key = top_level_key.strip(' #')
-            top_level_keys.append(top_level_key)
-    if line.startswith('['):
-        cur_section = line[1:-1]
-        if cur_section.startswith('target'):
-            cur_section = 'target'
-        elif '.' in cur_section:
-            raise RuntimeError("don't know how to deal with section: {}".format(cur_section))
-        sections[cur_section] = [line]
-        section_order.append(cur_section)
-    else:
-        sections[cur_section].append(line)
-
-# Fill out the `targets` array by giving all configured targets a copy of the
-# `target` section we just loaded from the example config
-configured_targets = [build()]
-if 'build' in config:
-    if 'host' in config['build']:
-        configured_targets += config['build']['host']
-    if 'target' in config['build']:
-        configured_targets += config['build']['target']
-if 'target' in config:
-    for target in config['target']:
-        configured_targets.append(target)
-for target in configured_targets:
-    targets[target] = sections['target'][:]
-    # For `.` to be valid TOML, it needs to be quoted. But `bootstrap.py` doesn't use a proper TOML parser and fails to parse the target.
-    # Avoid using quotes unless it's necessary.
-    targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", "'{}'".format(target) if "." in target else target)
+def parse_example_config(known_args, config):
+    sections = {}
+    cur_section = None
+    sections[None] = []
+    section_order = [None]
+    targets = {}
+    top_level_keys = []
+
+    for line in open(rust_dir + '/config.example.toml').read().split("\n"):
+        if cur_section == None:
+            if line.count('=') == 1:
+                top_level_key = line.split('=')[0]
+                top_level_key = top_level_key.strip(' #')
+                top_level_keys.append(top_level_key)
+        if line.startswith('['):
+            cur_section = line[1:-1]
+            if cur_section.startswith('target'):
+                cur_section = 'target'
+            elif '.' in cur_section:
+                raise RuntimeError("don't know how to deal with section: {}".format(cur_section))
+            sections[cur_section] = [line]
+            section_order.append(cur_section)
+        else:
+            sections[cur_section].append(line)
+
+    # Fill out the `targets` array by giving all configured targets a copy of the
+    # `target` section we just loaded from the example config
+    configured_targets = [build(known_args)]
+    if 'build' in config:
+        if 'host' in config['build']:
+            configured_targets += config['build']['host']
+        if 'target' in config['build']:
+            configured_targets += config['build']['target']
+    if 'target' in config:
+        for target in config['target']:
+            configured_targets.append(target)
+    for target in configured_targets:
+        targets[target] = sections['target'][:]
+        # For `.` to be valid TOML, it needs to be quoted. But `bootstrap.py` doesn't use a proper TOML parser and fails to parse the target.
+        # Avoid using quotes unless it's necessary.
+        targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", "'{}'".format(target) if "." in target else target)
+
+    configure_file(sections, top_level_keys, targets, config)
+    return section_order, sections, targets
 
 
 def is_number(value):
@@ -475,17 +481,20 @@ def configure_top_level_key(lines, top_level_key, value):
     raise RuntimeError("failed to find config line for {}".format(top_level_key))
 
 
-for section_key, section_config in config.items():
-    if section_key not in sections and section_key not in top_level_keys:
-        raise RuntimeError("config key {} not in sections or top_level_keys".format(section_key))
-    if section_key in top_level_keys:
-        configure_top_level_key(sections[None], section_key, section_config)
+# Modify `sections` to reflect the parsed arguments and example configs.
+def configure_file(sections, top_level_keys, targets, config):
+    for section_key, section_config in config.items():
+        if section_key not in sections and section_key not in top_level_keys:
+            raise RuntimeError("config key {} not in sections or top_level_keys".format(section_key))
+        if section_key in top_level_keys:
+            configure_top_level_key(sections[None], section_key, section_config)
+
+        elif  section_key == 'target':
+            for target in section_config:
+                configure_section(targets[target], section_config[target])
+        else:
+            configure_section(sections[section_key], section_config)
 
-    elif  section_key == 'target':
-        for target in section_config:
-            configure_section(targets[target], section_config[target])
-    else:
-        configure_section(sections[section_key], section_config)
 
 def write_uncommented(target, f):
     block = []
@@ -503,24 +512,36 @@ def write_uncommented(target, f):
         is_comment = is_comment and line.startswith('#')
     return f
 
-# Now that we've built up our `config.toml`, write it all out in the same
-# order that we read it in.
-p("")
-p("writing `config.toml` in current directory")
-with bootstrap.output('config.toml') as f:
+
+def write_config_toml(writer, section_order, targets, sections):
     for section in section_order:
         if section == 'target':
             for target in targets:
-                f = write_uncommented(targets[target], f)
+                writer = write_uncommented(targets[target], writer)
         else:
-            f = write_uncommented(sections[section], f)
-
-with bootstrap.output('Makefile') as f:
-    contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
-    contents = open(contents).read()
-    contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')
-    contents = contents.replace("$(CFG_PYTHON)", sys.executable)
-    f.write(contents)
-
-p("")
-p("run `python {}/x.py --help`".format(rust_dir))
+            writer = write_uncommented(sections[section], writer)
+
+
+if __name__ == "__main__":
+    p("processing command line")
+    # Parse all known arguments into a configuration structure that reflects the
+    # TOML we're going to write out
+    p("")
+    section_order, sections, targets = parse_args(sys.argv[1:])
+
+    # Now that we've built up our `config.toml`, write it all out in the same
+    # order that we read it in.
+    p("")
+    p("writing `config.toml` in current directory")
+    with bootstrap.output('config.toml') as f:
+        write_config_toml(f, section_order, targets, sections)
+
+    with bootstrap.output('Makefile') as f:
+        contents = os.path.join(rust_dir, 'src', 'bootstrap', 'mk', 'Makefile.in')
+        contents = open(contents).read()
+        contents = contents.replace("$(CFG_SRC_DIR)", rust_dir + '/')
+        contents = contents.replace("$(CFG_PYTHON)", sys.executable)
+        f.write(contents)
+
+    p("")
+    p("run `python {}/x.py --help`".format(rust_dir))
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 41ee5096553..dff46b500e3 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -567,6 +567,8 @@ fn configure_cmake(
             cfg.define("CMAKE_SYSTEM_NAME", "Haiku");
         } else if target.contains("solaris") || target.contains("illumos") {
             cfg.define("CMAKE_SYSTEM_NAME", "SunOS");
+        } else if target.contains("linux") {
+            cfg.define("CMAKE_SYSTEM_NAME", "Linux");
         }
         // When cross-compiling we should also set CMAKE_SYSTEM_VERSION, but in
         // that case like CMake we cannot easily determine system version either.
diff --git a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
index 889a586b351..b5715024a84 100644
--- a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile
@@ -1,6 +1,8 @@
 FROM ubuntu:22.04
 
 ARG DEBIAN_FRONTEND=noninteractive
+# NOTE: intentionally uses python2 for x.py so we can test it still works.
+# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
   make \
@@ -8,6 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   file \
   curl \
   ca-certificates \
+  python2.7 \
   python3 \
   python3-pip \
   python3-pkg-resources \
@@ -30,4 +33,4 @@ RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-require
 COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
-ENV SCRIPT python3 ../x.py test --stage 0 src/tools/tidy tidyselftest
+ENV SCRIPT python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile
index a007bf183ee..dc8a4aac768 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile
@@ -2,7 +2,6 @@ FROM ubuntu:22.04
 
 ARG DEBIAN_FRONTEND=noninteractive
 
-# NOTE: intentionally installs both python2 and python3 so we can test support for both.
 RUN apt-get update && apt-get install -y --no-install-recommends \
   g++ \
   gcc-multilib \
@@ -11,8 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   file \
   curl \
   ca-certificates \
-  python2.7 \
-  python3 \
+  python3.11 \
   git \
   cmake \
   sudo \
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 989e091a0d2..e3e5454ef54 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -39,6 +39,7 @@ use std::hash::Hash;
 use std::mem;
 use thin_vec::ThinVec;
 
+use crate::clean::inline::merge_attrs;
 use crate::core::{self, DocContext, ImplTraitParam};
 use crate::formats::item_type::ItemType;
 use crate::visit_ast::Module as DocModule;
@@ -2373,21 +2374,22 @@ fn clean_maybe_renamed_item<'tcx>(
             _ => unreachable!("not yet converted"),
         };
 
-        let mut extra_attrs = Vec::new();
+        let mut import_attrs = Vec::new();
+        let mut target_attrs = Vec::new();
         if let Some(import_id) = import_id &&
             let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id)
         {
             let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some();
             // Then we get all the various imports' attributes.
-            get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline);
-            add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline);
+            get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut import_attrs, is_inline);
+            add_without_unwanted_attributes(&mut target_attrs, inline::load_attrs(cx, def_id), is_inline);
         } else {
             // We only keep the item's attributes.
-            extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
+            target_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
         }
 
-        let attrs = Attributes::from_ast(&extra_attrs);
-        let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
+        let import_parent = import_id.map(|import_id| cx.tcx.local_parent(import_id).to_def_id());
+        let (attrs, cfg) =  merge_attrs(cx, import_parent, &target_attrs, Some(&import_attrs));
 
         let mut item =
             Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index b296aa2f4e6..8286bd506bc 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -9,6 +9,6 @@ clap = "4.0.32"
 env_logger = "0.7.1"
 
 [dependencies.mdbook]
-version = "0.4.25"
+version = "0.4.28"
 default-features = false
 features = ["search"]
diff --git a/tests/rustdoc-ui/intra-doc/import-inline-merge.rs b/tests/rustdoc-ui/intra-doc/import-inline-merge.rs
new file mode 100644
index 00000000000..31fef032b0f
--- /dev/null
+++ b/tests/rustdoc-ui/intra-doc/import-inline-merge.rs
@@ -0,0 +1,16 @@
+// Import for `A` is inlined and doc comments on the import and `A` itself are merged.
+// After the merge they still have correct parent scopes to resolve both `[A]` and `[B]`.
+
+// check-pass
+
+#![allow(rustdoc::private_intra_doc_links)]
+
+mod m {
+    /// [B]
+    pub struct A {}
+
+    pub struct B {}
+}
+
+/// [A]
+pub use m::A;
diff --git a/tests/ui/async-await/in-trait/issue-102310.rs b/tests/ui/async-await/in-trait/issue-102310.rs
index 49c3e9feeb4..8e5dbd08eb9 100644
--- a/tests/ui/async-await/in-trait/issue-102310.rs
+++ b/tests/ui/async-await/in-trait/issue-102310.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/lifetime-mismatch.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr
index d87adcc78b6..0e9477544a4 100644
--- a/tests/ui/async-await/in-trait/lifetime-mismatch.stderr
+++ b/tests/ui/async-await/in-trait/lifetime-mismatch.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/lifetime-mismatch.rs:3:12
+  --> $DIR/lifetime-mismatch.rs:5:12
    |
 LL | #![feature(async_fn_in_trait)]
    |            ^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | #![feature(async_fn_in_trait)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
-  --> $DIR/lifetime-mismatch.rs:12:17
+  --> $DIR/lifetime-mismatch.rs:14:17
    |
 LL |     async fn foo<'a>(&self);
    |                 ---- lifetimes in impl do not match this method in trait
diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
new file mode 100644
index 00000000000..0e9477544a4
--- /dev/null
+++ b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr
@@ -0,0 +1,21 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/lifetime-mismatch.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[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+  --> $DIR/lifetime-mismatch.rs:14:17
+   |
+LL |     async fn foo<'a>(&self);
+   |                 ---- lifetimes in impl do not match this method in trait
+...
+LL |     async fn foo(&self) {}
+   |                 ^ lifetimes do not match method in trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.rs b/tests/ui/async-await/in-trait/lifetime-mismatch.rs
index 45ede193c0f..5ff5a01a1ee 100644
--- a/tests/ui/async-await/in-trait/lifetime-mismatch.rs
+++ b/tests/ui/async-await/in-trait/lifetime-mismatch.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/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs
new file mode 100644
index 00000000000..734a3786294
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs
@@ -0,0 +1,11 @@
+#![feature(generic_const_exprs)]
+//~^ WARN the feature `generic_const_exprs` is incomplete
+
+trait B {
+    type U<T>;
+}
+
+fn f<T: B<U<1i32> = ()>>() {}
+//~^ ERROR constant provided when a type was expected
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr
new file mode 100644
index 00000000000..8b6eb5b7594
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr
@@ -0,0 +1,18 @@
+warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/mismatched-gat-subst-kind.rs:1:12
+   |
+LL | #![feature(generic_const_exprs)]
+   |            ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0747]: constant provided when a type was expected
+  --> $DIR/mismatched-gat-subst-kind.rs:8:13
+   |
+LL | fn f<T: B<U<1i32> = ()>>() {}
+   |             ^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/impl-trait/in-trait/early.rs b/tests/ui/impl-trait/in-trait/early.rs
index 9c1c2b50339..831033a5880 100644
--- a/tests/ui/impl-trait/in-trait/early.rs
+++ b/tests/ui/impl-trait/in-trait/early.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, return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/impl-trait/in-trait/issue-102301.rs b/tests/ui/impl-trait/in-trait/issue-102301.rs
index a93714a658e..1329ca29d06 100644
--- a/tests/ui/impl-trait/in-trait/issue-102301.rs
+++ b/tests/ui/impl-trait/in-trait/issue-102301.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/opaque-in-impl.rs b/tests/ui/impl-trait/in-trait/opaque-in-impl.rs
index 2e06629699a..f48d9fa26c0 100644
--- a/tests/ui/impl-trait/in-trait/opaque-in-impl.rs
+++ b/tests/ui/impl-trait/in-trait/opaque-in-impl.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/trait-more-generics-than-impl.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr
index 8ff54cad951..64c942705cf 100644
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.stderr
+++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr
@@ -1,5 +1,5 @@
 error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/trait-more-generics-than-impl.rs:11:11
+  --> $DIR/trait-more-generics-than-impl.rs:14:11
    |
 LL |     fn bar<T>() -> impl Sized;
    |            - expected 1 type parameter
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr
new file mode 100644
index 00000000000..64c942705cf
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr
@@ -0,0 +1,12 @@
+error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
+  --> $DIR/trait-more-generics-than-impl.rs:14:11
+   |
+LL |     fn bar<T>() -> impl Sized;
+   |            - expected 1 type parameter
+...
+LL |     fn bar() -> impl Sized {}
+   |           ^ found 0 type parameters
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
index 0bbe50ea6fd..c2e394a1f66 100644
--- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.rs
+++ b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.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/where-clause.rs b/tests/ui/impl-trait/in-trait/where-clause.rs
index 87bac519cf3..88d86e2b541 100644
--- a/tests/ui/impl-trait/in-trait/where-clause.rs
+++ b/tests/ui/impl-trait/in-trait/where-clause.rs
@@ -1,5 +1,7 @@
 // check-pass
 // 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/rfc-2091-track-caller/intrinsic-wrapper.rs b/tests/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
index 87e52881c15..23d2a4b0a99 100644
--- a/tests/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
+++ b/tests/ui/rfc-2091-track-caller/intrinsic-wrapper.rs
@@ -1,5 +1,6 @@
 // run-pass
 // revisions: default mir-opt
+//[default] compile-flags: -Zinline-mir=no
 //[mir-opt] compile-flags: -Zmir-opt-level=4
 
 macro_rules! caller_location_from_macro {
@@ -9,13 +10,13 @@ macro_rules! caller_location_from_macro {
 fn main() {
     let loc = core::panic::Location::caller();
     assert_eq!(loc.file(), file!());
-    assert_eq!(loc.line(), 10);
+    assert_eq!(loc.line(), 11);
     assert_eq!(loc.column(), 15);
 
     // `Location::caller()` in a macro should behave similarly to `file!` and `line!`,
     // i.e. point to where the macro was invoked, instead of the macro itself.
     let loc2 = caller_location_from_macro!();
     assert_eq!(loc2.file(), file!());
-    assert_eq!(loc2.line(), 17);
+    assert_eq!(loc2.line(), 18);
     assert_eq!(loc2.column(), 16);
 }
diff --git a/tests/ui/rfc-2091-track-caller/mir-inlined-macro.rs b/tests/ui/rfc-2091-track-caller/mir-inlined-macro.rs
new file mode 100644
index 00000000000..a2e8eb27ede
--- /dev/null
+++ b/tests/ui/rfc-2091-track-caller/mir-inlined-macro.rs
@@ -0,0 +1,23 @@
+// run-pass
+// revisions: default mir-opt
+//[default] compile-flags: -Zinline-mir=no
+//[mir-opt] compile-flags: -Zmir-opt-level=4
+
+use std::panic::Location;
+
+macro_rules! f {
+    () => {
+        Location::caller()
+    };
+}
+
+#[inline(always)]
+fn g() -> &'static Location<'static> {
+    f!()
+}
+
+fn main() {
+    let loc = g();
+    assert_eq!(loc.line(), 16);
+    assert_eq!(loc.column(), 5);
+}