From f427698c03a74b961dbc5f28bc7a9801a77d0d44 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Tue, 15 Mar 2022 17:20:21 -0700
Subject: [PATCH 01/11] Parse inner attributes on inline const block

---
 compiler/rustc_ast_pretty/src/pprust/state.rs   |  2 +-
 .../rustc_ast_pretty/src/pprust/state/expr.rs   | 17 ++++++++++++++---
 compiler/rustc_parse/src/parser/mod.rs          |  4 ++--
 src/test/pretty/stmt_expr_attributes.rs         |  9 +++++++++
 4 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b2c62383fb69a..dc610da5dd089 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -960,7 +960,7 @@ impl<'a> State<'a> {
                 self.word_space("=");
                 match term {
                     Term::Ty(ty) => self.print_type(ty),
-                    Term::Const(c) => self.print_expr_anon_const(c),
+                    Term::Const(c) => self.print_expr_anon_const(c, &[]),
                 }
             }
             ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds),
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 6435f1b6141e3..9de4cbbee13f0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -88,10 +88,21 @@ impl<'a> State<'a> {
         self.end();
     }
 
-    pub(super) fn print_expr_anon_const(&mut self, expr: &ast::AnonConst) {
+    pub(super) fn print_expr_anon_const(
+        &mut self,
+        expr: &ast::AnonConst,
+        attrs: &[ast::Attribute],
+    ) {
         self.ibox(INDENT_UNIT);
         self.word("const");
-        self.print_expr(&expr.value);
+        self.nbsp();
+        if let ast::ExprKind::Block(block, None) = &expr.value.kind {
+            self.cbox(0);
+            self.ibox(0);
+            self.print_block_with_attrs(block, attrs);
+        } else {
+            self.print_expr(&expr.value);
+        }
         self.end();
     }
 
@@ -275,7 +286,7 @@ impl<'a> State<'a> {
                 self.print_expr_vec(exprs);
             }
             ast::ExprKind::ConstBlock(ref anon_const) => {
-                self.print_expr_anon_const(anon_const);
+                self.print_expr_anon_const(anon_const, attrs);
             }
             ast::ExprKind::Repeat(ref element, ref count) => {
                 self.print_expr_repeat(element, count);
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 4e229918b6362..ffa4f7fed2dc8 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1105,13 +1105,13 @@ impl<'a> Parser<'a> {
             self.sess.gated_spans.gate(sym::inline_const, span);
         }
         self.eat_keyword(kw::Const);
-        let blk = self.parse_block()?;
+        let (attrs, blk) = self.parse_inner_attrs_and_block()?;
         let anon_const = AnonConst {
             id: DUMMY_NODE_ID,
             value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()),
         };
         let blk_span = anon_const.value.span;
-        Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::new()))
+        Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::from(attrs)))
     }
 
     /// Parses mutability (`mut` or nothing).
diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs
index 7ab22f1960c2d..c01379065d1cd 100644
--- a/src/test/pretty/stmt_expr_attributes.rs
+++ b/src/test/pretty/stmt_expr_attributes.rs
@@ -1,6 +1,8 @@
 // pp-exact
 
 #![feature(box_syntax)]
+#![feature(inline_const)]
+#![feature(inline_const_pat)]
 #![feature(rustc_attrs)]
 #![feature(stmt_expr_attributes)]
 
@@ -16,6 +18,7 @@ fn _1() {
 
     #[rustc_dummy]
     unsafe {
+        #![rustc_dummy]
         // code
     }
 }
@@ -206,6 +209,12 @@ fn _11() {
             let _ = ();
             ()
         };
+    let const {
+                    #![rustc_dummy]
+                } =
+        #[rustc_dummy] const {
+                #![rustc_dummy]
+            };
     let mut x = 0;
     let _ = #[rustc_dummy] x = 15;
     let _ = #[rustc_dummy] x += 15;

From 9cfdb89999d3bdefc6c45047bbacb48c2416b5e8 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 13 Feb 2022 19:21:33 +0100
Subject: [PATCH 02/11] Only add codegen backend to dep info if
 -Zbinary-dep-depinfo is used

---
 compiler/rustc_interface/src/passes.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 4f30e78f5e2aa..7640b9a7413d4 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -646,11 +646,11 @@ fn write_out_deps(
         });
         files.extend(extra_tracked_files);
 
-        if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
-            files.push(backend.to_string());
-        }
-
         if sess.binary_dep_depinfo() {
+            if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
+                files.push(backend.to_string());
+            }
+
             boxed_resolver.borrow_mut().access(|resolver| {
                 for cnum in resolver.cstore().crates_untracked() {
                     let source = resolver.cstore().crate_source_untracked(cnum);

From c681a884efa99cd14301553aacc42b702eac8b00 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 13 Feb 2022 19:24:15 +0100
Subject: [PATCH 03/11] Don't include invalid paths in the depinfo for builtin
 backends

---
 compiler/rustc_interface/src/passes.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7640b9a7413d4..5a4b4df67723b 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -648,7 +648,11 @@ fn write_out_deps(
 
         if sess.binary_dep_depinfo() {
             if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
-                files.push(backend.to_string());
+                if backend.contains('.') {
+                    // If the backend name contain a `.`, it is the path to an external dynamic
+                    // library. If not, it is not a path.
+                    files.push(backend.to_string());
+                }
             }
 
             boxed_resolver.borrow_mut().access(|resolver| {

From 147e5da9e34b86cd213900748a9da12bceb33de2 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 24 Mar 2022 16:23:51 +0100
Subject: [PATCH 04/11] Add test

---
 .../hotplug_codegen_backend/Makefile          | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
index d8ceace7fff25..4cda243ffb5a3 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
@@ -2,10 +2,25 @@ include ../tools.mk
 
 # ignore-stage1
 
+# This test both exists as a check that -Zcodegen-backend is capable of loading external codegen
+# backends and that this external codegen backend is only included in the dep info if
+# -Zbinary-dep-depinfo is used.
+
 all:
 	/bin/echo || exit 0 # This test requires /bin/echo to exist
 	$(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
 		-o $(TMPDIR)/the_backend.dylib
+
+	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
+		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
+		--emit link,dep-info
+	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
+	# don't declare a dependency on the codegen backend if -Zbinary-dep-depinfo isn't used.
+	grep -v "the_backend.dylib" $(TMPDIR)/some_crate.d
+	
 	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
-		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options
-	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/some_crate
+		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
+		--emit link,dep-info -Zbinary-dep-depinfo
+	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
+	# but declare a dependency on the codegen backend if -Zbinary-dep-depinfo it used.
+	grep "the_backend.dylib" $(TMPDIR)/some_crate.d

From 8035796b9aabf1aa2a711694e40f00fe8a822f40 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Sat, 26 Mar 2022 18:23:32 -0400
Subject: [PATCH 05/11] Stablize `const_extern_fn` for "Rust" and "C"

All other ABIs are left unstable for now.

cc #64926
---
 compiler/rustc_ast_passes/src/feature_gate.rs | 37 +++++++------
 compiler/rustc_parse/src/parser/ty.rs         |  3 ++
 .../feature-gate-const_extern_fn.rs           | 17 +++---
 .../feature-gate-const_extern_fn.stderr       | 54 ++++---------------
 4 files changed, 42 insertions(+), 69 deletions(-)

diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 5b6147c72230d..5b2716b2dd088 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -58,9 +58,22 @@ struct PostExpansionVisitor<'a> {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: ast::StrLit) {
+    fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
         let ast::StrLit { symbol_unescaped, span, .. } = abi;
 
+        if let ast::Const::Yes(_) = constness {
+            match symbol_unescaped.as_str() {
+                // Stable
+                "Rust" | "C" => {}
+                abi => gate_feature_post!(
+                    &self,
+                    const_extern_fn,
+                    span,
+                    &format!("`{}` as a `const fn` ABI is unstable", abi)
+                ),
+            }
+        }
+
         match symbol_unescaped.as_str() {
             // Stable
             "Rust" | "C" | "cdecl" | "stdcall" | "fastcall" | "aapcs" | "win64" | "sysv64"
@@ -261,9 +274,9 @@ impl<'a> PostExpansionVisitor<'a> {
         }
     }
 
-    fn check_extern(&self, ext: ast::Extern) {
+    fn check_extern(&self, ext: ast::Extern, constness: ast::Const) {
         if let ast::Extern::Explicit(abi) = ext {
-            self.check_abi(abi);
+            self.check_abi(abi, constness);
         }
     }
 
@@ -445,7 +458,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
                 if let Some(abi) = foreign_module.abi {
-                    self.check_abi(abi);
+                    self.check_abi(abi, ast::Const::No);
                 }
             }
 
@@ -568,7 +581,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_extern(bare_fn_ty.ext);
+                // Function pointers cannot be `const`
+                self.check_extern(bare_fn_ty.ext, ast::Const::No);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
@@ -668,18 +682,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
         if let Some(header) = fn_kind.header() {
             // Stability of const fn methods are covered in `visit_assoc_item` below.
-            self.check_extern(header.ext);
-
-            if let (ast::Const::Yes(_), ast::Extern::Implicit)
-            | (ast::Const::Yes(_), ast::Extern::Explicit(_)) = (header.constness, header.ext)
-            {
-                gate_feature_post!(
-                    &self,
-                    const_extern_fn,
-                    span,
-                    "`const extern fn` definitions are unstable"
-                );
-            }
+            self.check_extern(header.ext, header.constness);
         }
 
         if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 436c5bd4fcac2..bb387064e27fe 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -523,6 +523,9 @@ impl<'a> Parser<'a> {
         let decl = self.parse_fn_decl(|_| false, AllowPlus::No, recover_return_sign)?;
         let whole_span = lo.to(self.prev_token.span);
         if let ast::Const::Yes(span) = constness {
+            // If we ever start to allow `const fn()`, then update
+            // feature gating for `#![feature(const_extern_fn)]` to
+            // cover it.
             self.error_fn_ptr_bad_qualifier(whole_span, span, "const");
         }
         if let ast::Async::Yes { span, .. } = asyncness {
diff --git a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs
index 5667d5535274d..f7bed91b03787 100644
--- a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs
+++ b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs
@@ -1,10 +1,13 @@
-// Check that `const extern fn` and `const unsafe extern fn` are feature-gated.
+// Check that `const extern fn` and `const unsafe extern fn` are feature-gated
+// for certain ABIs.
 
-const extern fn foo1() {} //~ ERROR `const extern fn` definitions are unstable
-const extern "C" fn foo2() {} //~ ERROR `const extern fn` definitions are unstable
-const extern "Rust" fn foo3() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern fn bar1() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern "C" fn bar2() {} //~ ERROR `const extern fn` definitions are unstable
-const unsafe extern "Rust" fn bar3() {} //~ ERROR `const extern fn` definitions are unstable
+const extern fn foo1() {}
+const extern "C" fn foo2() {}
+const extern "Rust" fn foo3() {}
+const extern "cdecl" fn foo4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
+const unsafe extern fn bar1() {}
+const unsafe extern "C" fn bar2() {}
+const unsafe extern "Rust" fn bar3() {}
+const unsafe extern "cdecl" fn bar4() {} //~ ERROR `cdecl` as a `const fn` ABI is unstable
 
 fn main() {}
diff --git a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr
index bd5940a3fd60c..f8c3107bd221a 100644
--- a/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr
+++ b/src/test/ui/consts/const-extern-fn/feature-gate-const_extern_fn.stderr
@@ -1,57 +1,21 @@
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:3:1
+error[E0658]: `cdecl` as a `const fn` ABI is unstable
+  --> $DIR/feature-gate-const_extern_fn.rs:7:14
    |
-LL | const extern fn foo1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const extern "cdecl" fn foo4() {}
+   |              ^^^^^^^
    |
    = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
    = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
 
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:4:1
+error[E0658]: `cdecl` as a `const fn` ABI is unstable
+  --> $DIR/feature-gate-const_extern_fn.rs:11:21
    |
-LL | const extern "C" fn foo2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const unsafe extern "cdecl" fn bar4() {}
+   |                     ^^^^^^^
    |
    = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
    = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
 
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:5:1
-   |
-LL | const extern "Rust" fn foo3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:6:1
-   |
-LL | const unsafe extern fn bar1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:7:1
-   |
-LL | const unsafe extern "C" fn bar2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error[E0658]: `const extern fn` definitions are unstable
-  --> $DIR/feature-gate-const_extern_fn.rs:8:1
-   |
-LL | const unsafe extern "Rust" fn bar3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #64926 <https://github.com/rust-lang/rust/issues/64926> for more information
-   = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.

From 6b75406f5a7b006f7c724c08c6a00d7696a3620d Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Mon, 28 Feb 2022 18:13:24 -0500
Subject: [PATCH 06/11] Create 2024 edition

---
 compiler/rustc_ast/src/token.rs               |  2 +-
 .../src/standard_library_imports.rs           |  1 +
 compiler/rustc_expand/src/mbe/macro_rules.rs  |  2 +-
 compiler/rustc_session/src/session.rs         |  5 ++++
 compiler/rustc_span/src/edition.rs            | 30 +++++++++++++++++--
 compiler/rustc_span/src/lib.rs                |  5 ++++
 compiler/rustc_span/src/symbol.rs             |  2 ++
 library/core/src/prelude/mod.rs               | 10 +++++++
 library/std/src/lib.rs                        |  1 +
 library/std/src/prelude/mod.rs                | 14 +++++++++
 src/test/ui/hello.rs                          | 11 +++++--
 src/test/ui/hello2021.rs                      |  6 ----
 src/tools/rustfmt/src/bin/main.rs             |  1 +
 src/tools/rustfmt/src/config/options.rs       |  5 ++++
 14 files changed, 83 insertions(+), 12 deletions(-)
 delete mode 100644 src/test/ui/hello2021.rs

diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 2132cdfc001b6..3e274107e7fb6 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -722,7 +722,7 @@ impl NonterminalKind {
                 Edition::Edition2015 | Edition::Edition2018 => {
                     NonterminalKind::PatParam { inferred: true }
                 }
-                Edition::Edition2021 => NonterminalKind::PatWithOr,
+                Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
             },
             sym::pat_param => NonterminalKind::PatParam { inferred: false },
             sym::expr => NonterminalKind::Expr,
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index 3571517d2b258..09ad5f9b3eaa9 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -70,6 +70,7 @@ pub fn inject(
             Edition2015 => sym::rust_2015,
             Edition2018 => sym::rust_2018,
             Edition2021 => sym::rust_2021,
+            Edition2024 => sym::rust_2024,
         }])
         .map(|&symbol| Ident::new(symbol, span))
         .collect();
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 10b2b9f07e2a5..058b03530a39f 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1033,7 +1033,7 @@ fn check_matcher_core(
                             err.span_label(sp, format!("not allowed after `{}` fragments", kind));
 
                             if kind == NonterminalKind::PatWithOr
-                                && sess.edition == Edition::Edition2021
+                                && sess.edition.rust_2021()
                                 && next_token.is_token(&BinOp(token::BinOpToken::Or))
                             {
                                 let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index eed0f1e09fffe..8ba859bed4d08 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -945,6 +945,11 @@ impl Session {
         self.opts.edition >= Edition::Edition2021
     }
 
+    /// Are we allowed to use features from the Rust 2024 edition?
+    pub fn rust_2024(&self) -> bool {
+        self.opts.edition >= Edition::Edition2024
+    }
+
     pub fn edition(&self) -> Edition {
         self.opts.edition
     }
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs
index 511c2e8662697..065d3660e5008 100644
--- a/compiler/rustc_span/src/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
@@ -22,13 +22,15 @@ pub enum Edition {
     Edition2018,
     /// The 2021 edition
     Edition2021,
+    /// The 2024 edition
+    Edition2024,
 }
 
 // Must be in order from oldest to newest.
 pub const ALL_EDITIONS: &[Edition] =
-    &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021];
+    &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024];
 
-pub const EDITION_NAME_LIST: &str = "2015|2018|2021";
+pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024";
 
 pub const DEFAULT_EDITION: Edition = Edition::Edition2015;
 
@@ -40,6 +42,7 @@ impl fmt::Display for Edition {
             Edition::Edition2015 => "2015",
             Edition::Edition2018 => "2018",
             Edition::Edition2021 => "2021",
+            Edition::Edition2024 => "2024",
         };
         write!(f, "{}", s)
     }
@@ -51,6 +54,7 @@ impl Edition {
             Edition::Edition2015 => "rust_2015_compatibility",
             Edition::Edition2018 => "rust_2018_compatibility",
             Edition::Edition2021 => "rust_2021_compatibility",
+            Edition::Edition2024 => "rust_2024_compatibility",
         }
     }
 
@@ -59,6 +63,7 @@ impl Edition {
             Edition::Edition2015 => sym::rust_2015_preview,
             Edition::Edition2018 => sym::rust_2018_preview,
             Edition::Edition2021 => sym::rust_2021_preview,
+            Edition::Edition2024 => sym::rust_2024_preview,
         }
     }
 
@@ -67,8 +72,28 @@ impl Edition {
             Edition::Edition2015 => true,
             Edition::Edition2018 => true,
             Edition::Edition2021 => true,
+            Edition::Edition2024 => false,
         }
     }
+
+    pub fn rust_2015(&self) -> bool {
+        *self == Edition::Edition2015
+    }
+
+    /// Are we allowed to use features from the Rust 2018 edition?
+    pub fn rust_2018(&self) -> bool {
+        *self >= Edition::Edition2018
+    }
+
+    /// Are we allowed to use features from the Rust 2021 edition?
+    pub fn rust_2021(&self) -> bool {
+        *self >= Edition::Edition2021
+    }
+
+    /// Are we allowed to use features from the Rust 2024 edition?
+    pub fn rust_2024(&self) -> bool {
+        *self >= Edition::Edition2024
+    }
 }
 
 impl FromStr for Edition {
@@ -78,6 +103,7 @@ impl FromStr for Edition {
             "2015" => Ok(Edition::Edition2015),
             "2018" => Ok(Edition::Edition2018),
             "2021" => Ok(Edition::Edition2021),
+            "2024" => Ok(Edition::Edition2024),
             _ => Err(()),
         }
     }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 6d7377927c291..9ae366a5fe811 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -698,6 +698,11 @@ impl Span {
         self.edition() >= edition::Edition::Edition2021
     }
 
+    #[inline]
+    pub fn rust_2024(self) -> bool {
+        self.edition() >= edition::Edition::Edition2024
+    }
+
     /// Returns the source callee.
     ///
     /// Returns `None` if the supplied span has no expansion trace,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2737c26708bc4..443f0a6db89ce 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1145,6 +1145,8 @@ symbols! {
         rust_2018_preview,
         rust_2021,
         rust_2021_preview,
+        rust_2024,
+        rust_2024_preview,
         rust_begin_unwind,
         rust_eh_catch_typeinfo,
         rust_eh_personality,
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index ccd36a428e296..3cd3a3b780e9c 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -45,3 +45,13 @@ pub mod rust_2021 {
     #[doc(no_inline)]
     pub use crate::convert::{TryFrom, TryInto};
 }
+
+/// The 2024 edition of the core prelude.
+///
+/// See the [module-level documentation](self) for more.
+#[unstable(feature = "prelude_2024", issue = "none")]
+pub mod rust_2024 {
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use super::rust_2021::*;
+}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 819ec10a4b4b6..a5cdc89c5b60e 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -279,6 +279,7 @@
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
 #![feature(portable_simd)]
+#![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
 #![feature(raw_os_nonzero)]
 #![feature(slice_internals)]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index d4bf6aeefee57..c314bbbb68e57 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -132,3 +132,17 @@ pub mod rust_2021 {
     #[doc(no_inline)]
     pub use core::prelude::rust_2021::*;
 }
+
+/// The 2024 version of the prelude of The Rust Standard Library.
+///
+/// See the [module-level documentation](self) for more.
+#[unstable(feature = "prelude_2024", issue = "none")]
+pub mod rust_2024 {
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use super::v1::*;
+
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use core::prelude::rust_2024::*;
+}
diff --git a/src/test/ui/hello.rs b/src/test/ui/hello.rs
index c207c25545eca..c66b7c60fb4ea 100644
--- a/src/test/ui/hello.rs
+++ b/src/test/ui/hello.rs
@@ -1,5 +1,12 @@
 // run-pass
+// revisions: e2015 e2018 e2021 e2024
 
-pub fn main() {
-    println!("hello, world");
+//[e2018] edition:2018
+//[e2021] edition:2021
+//[e2024] edition:2024
+
+//[e2024] compile-flags: -Zunstable-options
+
+fn main() {
+    println!("hello");
 }
diff --git a/src/test/ui/hello2021.rs b/src/test/ui/hello2021.rs
deleted file mode 100644
index 134d8af5bfb8a..0000000000000
--- a/src/test/ui/hello2021.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// run-pass
-// edition:2021
-
-fn main() {
-    println!("hello, 2021");
-}
diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs
index ad10b9ede608f..8e871e61f2683 100644
--- a/src/tools/rustfmt/src/bin/main.rs
+++ b/src/tools/rustfmt/src/bin/main.rs
@@ -693,6 +693,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
         "2015" => Ok(Edition::Edition2015),
         "2018" => Ok(Edition::Edition2018),
         "2021" => Ok(Edition::Edition2021),
+        "2024" => Ok(Edition::Edition2024),
         _ => Err(format_err!("Invalid value for `--edition`")),
     }
 }
diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs
index d857c29be29c6..257a17b2703a9 100644
--- a/src/tools/rustfmt/src/config/options.rs
+++ b/src/tools/rustfmt/src/config/options.rs
@@ -423,6 +423,10 @@ pub enum Edition {
     #[doc_hint = "2021"]
     /// Edition 2021.
     Edition2021,
+    #[value = "2024"]
+    #[doc_hint = "2024"]
+    /// Edition 2024.
+    Edition2024,
 }
 
 impl Default for Edition {
@@ -437,6 +441,7 @@ impl From<Edition> for rustc_span::edition::Edition {
             Edition::Edition2015 => Self::Edition2015,
             Edition::Edition2018 => Self::Edition2018,
             Edition::Edition2021 => Self::Edition2021,
+            Edition::Edition2024 => Self::Edition2024,
         }
     }
 }

From 7bd22e29d0d604e594ba03b51bd8c3fc82959215 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Wed, 6 Apr 2022 21:10:43 -0700
Subject: [PATCH 07/11] only downgrade Error -> Ambiguous if type error is in
 predicate

---
 .../src/traits/select/candidate_assembly.rs   |  4 ++--
 ...n-help-with-err-generic-is-not-function.rs |  8 --------
 ...lp-with-err-generic-is-not-function.stderr | 19 ++-----------------
 .../typeck/autoderef-with-param-env-error.rs  |  9 +++++++++
 .../autoderef-with-param-env-error.stderr     | 12 ++++++++++++
 5 files changed, 25 insertions(+), 27 deletions(-)
 create mode 100644 src/test/ui/typeck/autoderef-with-param-env-error.rs
 create mode 100644 src/test/ui/typeck/autoderef-with-param-env-error.stderr

diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index cf472813e9e32..4bb0ce29b637b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -231,8 +231,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
             // emitting additional spurious errors, since we're guaranteed
             // to have emitted at least one.
-            if stack.obligation.references_error() {
-                debug!("no results for error type, treating as ambiguous");
+            if stack.obligation.predicate.references_error() {
+                debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous");
                 return Ok(None);
             }
             return Err(Unimplemented);
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
index 26deb59876268..e48ab4aa96fb9 100644
--- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
@@ -8,15 +8,7 @@ where
     //~^ ERROR cannot find type `T` in this scope
     //~| NOTE not found in this scope
 {
-    // The part where it claims that there is no method named `len` is a bug. Feel free to fix it.
-    // This test is intended to ensure that a different bug, where it claimed
-    // that `v` was a function, does not regress.
     fn method(v: Vec<u8>) { v.len(); }
-    //~^ ERROR type annotations needed
-    //~| NOTE cannot infer type
-    //~| NOTE type must be known at this point
-    //~| ERROR no method named `len`
-    //~| NOTE private field, not a method
 }
 
 fn main() {}
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
index 958ce3c25d027..26bdf460f5e4d 100644
--- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
@@ -12,21 +12,6 @@ error[E0412]: cannot find type `T` in this scope
 LL |     T: Copy,
    |     ^ not found in this scope
 
-error[E0282]: type annotations needed
-  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
-   |
-LL |     fn method(v: Vec<u8>) { v.len(); }
-   |                               ^^^ cannot infer type
-   |
-   = note: type must be known at this point
-
-error[E0599]: no method named `len` found for struct `Vec<u8>` in the current scope
-  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
-   |
-LL |     fn method(v: Vec<u8>) { v.len(); }
-   |                               ^^^ private field, not a method
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0282, E0412, E0599.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.rs b/src/test/ui/typeck/autoderef-with-param-env-error.rs
new file mode 100644
index 0000000000000..ec96c61c63e3a
--- /dev/null
+++ b/src/test/ui/typeck/autoderef-with-param-env-error.rs
@@ -0,0 +1,9 @@
+fn foo()
+where
+    T: Send,
+    //~^ cannot find type `T` in this scope
+{
+    let s = "abc".to_string();
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.stderr b/src/test/ui/typeck/autoderef-with-param-env-error.stderr
new file mode 100644
index 0000000000000..cde800336dd3d
--- /dev/null
+++ b/src/test/ui/typeck/autoderef-with-param-env-error.stderr
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/autoderef-with-param-env-error.rs:3:5
+   |
+LL | fn foo()
+   |       - help: you might be missing a type parameter: `<T>`
+LL | where
+LL |     T: Send,
+   |     ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.

From abf2b4c04d4d6a0a2c49562fde33ae1d46e6ead7 Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Mon, 28 Feb 2022 15:33:50 -0500
Subject: [PATCH 08/11] Stabilize `derive_default_enum`

---
 .../src/deriving/default.rs                   | 13 +----
 compiler/rustc_feature/src/accepted.rs        |  2 +
 compiler/rustc_feature/src/active.rs          |  2 -
 compiler/rustc_feature/src/lib.rs             |  2 +-
 compiler/rustc_infer/src/lib.rs               |  2 +-
 compiler/rustc_middle/src/lib.rs              |  2 +-
 compiler/rustc_session/src/lib.rs             |  2 +-
 compiler/rustc_trait_selection/src/lib.rs     |  2 +-
 library/core/src/lib.rs                       |  2 +-
 src/test/ui/deriving/deriving-default-enum.rs |  2 -
 src/test/ui/deriving/deriving-with-helper.rs  |  1 -
 .../feature-gate-derive_default_enum.rs       |  7 ---
 .../feature-gate-derive_default_enum.stderr   | 13 -----
 src/test/ui/macros/macros-nonfatal-errors.rs  |  1 -
 .../ui/macros/macros-nonfatal-errors.stderr   | 58 +++++++++----------
 15 files changed, 38 insertions(+), 73 deletions(-)
 delete mode 100644 src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
 delete mode 100644 src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr

diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index ca83941f600ca..2c5260616c7da 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -46,18 +46,7 @@ pub fn expand_deriving_default(
                     StaticStruct(_, fields) => {
                         default_struct_substructure(cx, trait_span, substr, fields)
                     }
-                    StaticEnum(enum_def, _) => {
-                        if !cx.sess.features_untracked().derive_default_enum {
-                            rustc_session::parse::feature_err(
-                                cx.parse_sess(),
-                                sym::derive_default_enum,
-                                span,
-                                "deriving `Default` on enums is experimental",
-                            )
-                            .emit();
-                        }
-                        default_enum_substructure(cx, trait_span, enum_def)
-                    }
+                    StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def),
                     _ => cx.span_bug(trait_span, "method in `derive(Default)`"),
                 }
             })),
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index e37251c9c2439..048039343a7a2 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -126,6 +126,8 @@ declare_features! (
     (accepted, default_type_params, "1.0.0", None, None),
     /// Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
+    /// Allows `#[derive(Default)]` and `#[default]` on enums.
+    (accepted, derive_default_enum, "1.62.0", Some(86985), None),
     /// Allows the use of destructuring assignments.
     (accepted, destructuring_assignment, "1.59.0", Some(71126), None),
     /// Allows `#[doc(alias = "...")]`.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 28466315c8687..81863162df318 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -368,8 +368,6 @@ declare_features! (
     (active, deprecated_safe, "1.61.0", Some(94978), None),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (active, deprecated_suggestion, "1.61.0", Some(94785), None),
-    /// Allows `#[derive(Default)]` and `#[default]` on enums.
-    (active, derive_default_enum, "1.56.0", Some(86985), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
     (active, doc_auto_cfg, "1.58.0", Some(43781), None),
     /// Allows `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index bfc537cfae2cb..940c4ecdcc23a 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -11,7 +11,7 @@
 //! even if it is stabilized or removed, *do not remove it*. Instead, move the
 //! symbol to the `accepted` or `removed` modules respectively.
 
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(once_cell)]
 
 mod accepted;
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 08e005364ce64..e859bcaec1206 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -17,7 +17,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(extend_one)]
 #![feature(label_break_value)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index fa2dad5ce25f0..cffcd6699b6e4 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -30,7 +30,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(core_intrinsics)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(get_mut_unchecked)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 3151b025ffff7..054b18b6b633a 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,7 +1,7 @@
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 7523b8441013a..2ae7f34a91e00 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -16,7 +16,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(label_break_value)]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 660f6d92fe184..dc6bec246b9fe 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -167,7 +167,7 @@
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
 #![feature(decl_macro)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs
index 931ff1a5847d4..d1a81c72c2fdc 100644
--- a/src/test/ui/deriving/deriving-default-enum.rs
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(derive_default_enum)]
-
 // nb: does not impl Default
 #[derive(Debug, PartialEq)]
 struct NotDefault;
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
index d8f0b27a2e5f6..1c30b0b6fba75 100644
--- a/src/test/ui/deriving/deriving-with-helper.rs
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -5,7 +5,6 @@
 #![feature(lang_items)]
 #![feature(no_core)]
 #![feature(rustc_attrs)]
-#![feature(derive_default_enum)]
 
 #![no_core]
 
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
deleted file mode 100644
index 05a5d4e14223a..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental
-enum Foo {
-    #[default]
-    Alpha,
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
deleted file mode 100644
index 58dd4d508a709..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: deriving `Default` on enums is experimental
-  --> $DIR/feature-gate-derive_default_enum.rs:1:10
-   |
-LL | #[derive(Default)]
-   |          ^^^^^^^
-   |
-   = note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information
-   = help: add `#![feature(derive_default_enum)]` to the crate attributes to enable
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs
index 98f64aa6f8025..e7a01f105de0b 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.rs
+++ b/src/test/ui/macros/macros-nonfatal-errors.rs
@@ -5,7 +5,6 @@
 
 #![feature(trace_macros, concat_idents)]
 #![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
-#![feature(derive_default_enum)]
 
 use std::arch::asm;
 
diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr
index 79e8db9c1d429..b3c6d07f96763 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.stderr
+++ b/src/test/ui/macros/macros-nonfatal-errors.stderr
@@ -1,41 +1,41 @@
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:14:5
+  --> $DIR/macros-nonfatal-errors.rs:13:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:19:36
+  --> $DIR/macros-nonfatal-errors.rs:18:36
    |
 LL | struct DefaultInnerAttrTupleStruct(#[default] ());
    |                                    ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:23:1
+  --> $DIR/macros-nonfatal-errors.rs:22:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:27:1
+  --> $DIR/macros-nonfatal-errors.rs:26:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:37:11
+  --> $DIR/macros-nonfatal-errors.rs:36:11
    |
 LL |     Foo = #[default] 0,
    |           ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:38:14
+  --> $DIR/macros-nonfatal-errors.rs:37:14
    |
 LL |     Bar([u8; #[default] 1]),
    |              ^^^^^^^^^^
 
 error: no default declared
-  --> $DIR/macros-nonfatal-errors.rs:43:10
+  --> $DIR/macros-nonfatal-errors.rs:42:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -44,7 +44,7 @@ LL | #[derive(Default)]
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: multiple declared defaults
-  --> $DIR/macros-nonfatal-errors.rs:49:10
+  --> $DIR/macros-nonfatal-errors.rs:48:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -62,7 +62,7 @@ LL |     Baz,
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `#[default]` attribute does not accept a value
-  --> $DIR/macros-nonfatal-errors.rs:61:5
+  --> $DIR/macros-nonfatal-errors.rs:60:5
    |
 LL |     #[default = 1]
    |     ^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     #[default = 1]
    = help: try using `#[default]`
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:69:5
+  --> $DIR/macros-nonfatal-errors.rs:68:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -81,13 +81,13 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing this
-  --> $DIR/macros-nonfatal-errors.rs:68:5
+  --> $DIR/macros-nonfatal-errors.rs:67:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:79:5
+  --> $DIR/macros-nonfatal-errors.rs:78:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -99,7 +99,7 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing these
-  --> $DIR/macros-nonfatal-errors.rs:76:5
+  --> $DIR/macros-nonfatal-errors.rs:75:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:86:5
+  --> $DIR/macros-nonfatal-errors.rs:85:5
    |
 LL |     Foo {},
    |     ^^^
@@ -117,7 +117,7 @@ LL |     Foo {},
    = help: consider a manual implementation of `Default`
 
 error: default variant must be exhaustive
-  --> $DIR/macros-nonfatal-errors.rs:94:5
+  --> $DIR/macros-nonfatal-errors.rs:93:5
    |
 LL |     #[non_exhaustive]
    |     ----------------- declared `#[non_exhaustive]` here
@@ -127,37 +127,37 @@ LL |     Foo,
    = help: consider a manual implementation of `Default`
 
 error: asm template must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:99:10
+  --> $DIR/macros-nonfatal-errors.rs:98:10
    |
 LL |     asm!(invalid);
    |          ^^^^^^^
 
 error: concat_idents! requires ident args
-  --> $DIR/macros-nonfatal-errors.rs:102:5
+  --> $DIR/macros-nonfatal-errors.rs:101:5
    |
 LL |     concat_idents!("not", "idents");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:104:17
+  --> $DIR/macros-nonfatal-errors.rs:103:17
    |
 LL |     option_env!(invalid);
    |                 ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:105:10
+  --> $DIR/macros-nonfatal-errors.rs:104:10
    |
 LL |     env!(invalid);
    |          ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:106:10
+  --> $DIR/macros-nonfatal-errors.rs:105:10
    |
 LL |     env!(foo, abr, baz);
    |          ^^^
 
 error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
-  --> $DIR/macros-nonfatal-errors.rs:107:5
+  --> $DIR/macros-nonfatal-errors.rs:106:5
    |
 LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: format argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:109:13
+  --> $DIR/macros-nonfatal-errors.rs:108:13
    |
 LL |     format!(invalid);
    |             ^^^^^^^
@@ -176,19 +176,19 @@ LL |     format!("{}", invalid);
    |             +++++
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:111:14
+  --> $DIR/macros-nonfatal-errors.rs:110:14
    |
 LL |     include!(invalid);
    |              ^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:113:18
+  --> $DIR/macros-nonfatal-errors.rs:112:18
    |
 LL |     include_str!(invalid);
    |                  ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:114:5
+  --> $DIR/macros-nonfatal-errors.rs:113:5
    |
 LL |     include_str!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,13 +196,13 @@ LL |     include_str!("i'd be quite surprised if a file with this name existed")
    = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:115:20
+  --> $DIR/macros-nonfatal-errors.rs:114:20
    |
 LL |     include_bytes!(invalid);
    |                    ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:116:5
+  --> $DIR/macros-nonfatal-errors.rs:115:5
    |
 LL |     include_bytes!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,13 +210,13 @@ LL |     include_bytes!("i'd be quite surprised if a file with this name existed
    = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: trace_macros! accepts only `true` or `false`
-  --> $DIR/macros-nonfatal-errors.rs:118:5
+  --> $DIR/macros-nonfatal-errors.rs:117:5
    |
 LL |     trace_macros!(invalid);
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find macro `llvm_asm` in this scope
-  --> $DIR/macros-nonfatal-errors.rs:100:5
+  --> $DIR/macros-nonfatal-errors.rs:99:5
    |
 LL |     llvm_asm!(invalid);
    |     ^^^^^^^^

From a3dd654ae9f9002d3ff47e45a9a9b6afcb484d2f Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Tue, 8 Mar 2022 15:44:52 -0500
Subject: [PATCH 09/11] Add documentation

---
 library/core/src/default.rs | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index fb862f7df947b..1ce00828bf344 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -52,6 +52,23 @@
 /// This trait can be used with `#[derive]` if all of the type's fields implement
 /// `Default`. When `derive`d, it will use the default value for each field's type.
 ///
+/// ### `enum`s
+///
+/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be
+/// default. You do this by placing the `#[default]` attribute on the variant.
+///
+/// ```
+/// #[derive(Default)]
+/// enum Kind {
+///     #[default]
+///     A,
+///     B,
+///     C,
+/// }
+/// ```
+///
+/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants.
+///
 /// ## How can I implement `Default`?
 ///
 /// Provide an implementation for the `default()` method that returns the value of

From 69de21385e90d58c226ab688d04806a5c82259e3 Mon Sep 17 00:00:00 2001
From: Joshua Nelson <jnelson@cloudflare.com>
Date: Tue, 12 Apr 2022 20:11:10 -0500
Subject: [PATCH 10/11] Fix `x test --doc --stage 0 library/std`

I managed to break this in https://github.com/rust-lang/rust/pull/95449.
I am not quite sure why this is the correct fix, but it doesn't break `doc --stage 0`
and is strictly closer to the previous behavior.

Previously, rustdoc would error with strange issues because of the mismatched sysroot:
```
error[E0460]: found possibly newer version of crate `std` which `rustc_span` depends on
  --> /home/jnelson/rust-lang/rust/compiler/rustc_lint_defs/src/lib.rs:14:5
   |
14 | use rustc_span::{sym, symbol::Ident, Span, Symbol};
   |     ^^^^^^^^^^
   |
   = note: perhaps that crate needs to be recompiled?
   = note: the following crate versions were found:
           crate `std`: /home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-ff9290e971253a38.rlib
           crate `std`: /home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-ff9290e971253a38.so
           crate `rustc_span`: /home/jnelson/rust-lang/rust/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_span-ed11dce30c1766f9.rlib
```
---
 src/bootstrap/bin/rustdoc.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 4bba2eb450744..0349277a36b90 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -31,7 +31,9 @@ fn main() {
 
     let mut cmd = Command::new(rustdoc);
 
-    if target.is_some() {
+    // I am not actually sure why it's necessary to pass the sysroot for `--test`,
+    // but `test --doc --stage 0` is broken without it :(
+    if target.is_some() || args.iter().any(|x| x == "--test") {
         // The stage0 compiler has a special sysroot distinct from what we
         // actually downloaded, so we just always pass the `--sysroot` option,
         // unless one is already set.

From c20bb1d59f17c6329ea922c4bb2ccec5d46e7e00 Mon Sep 17 00:00:00 2001
From: ouz-a <oguz.agcayazi@gmail.com>
Date: Thu, 14 Apr 2022 23:42:15 +0300
Subject: [PATCH 11/11] Update issue-92893.stderr

---
 compiler/rustc_middle/src/middle/region.rs    |  9 +++------
 .../rustc_mir_build/src/build/matches/mod.rs  | 10 ++++++----
 .../src/check/generator_interior.rs           |  2 +-
 src/test/ui/mir/issue-92893.rs                |  7 +++++++
 src/test/ui/mir/issue-92893.stderr            | 20 +++++++++++++++++++
 .../src/loops/needless_range_loop.rs          |  4 ++--
 src/tools/clippy/clippy_lints/src/shadow.rs   |  4 ++--
 7 files changed, 41 insertions(+), 15 deletions(-)
 create mode 100644 src/test/ui/mir/issue-92893.rs
 create mode 100644 src/test/ui/mir/issue-92893.stderr

diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 98da20baf026b..af16e5e3fc871 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -362,12 +362,9 @@ impl ScopeTree {
         self.parent_map.get(&id).cloned().map(|(p, _)| p)
     }
 
-    /// Returns the lifetime of the local variable `var_id`
-    pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
-        self.var_map
-            .get(&var_id)
-            .cloned()
-            .unwrap_or_else(|| bug!("no enclosing scope for id {:?}", var_id))
+    /// Returns the lifetime of the local variable `var_id`, if any.
+    pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
+        self.var_map.get(&var_id).cloned()
     }
 
     /// Returns the scope when the temp created by `expr_id` will be cleaned up.
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 219d101aa7ccf..d45ae19752e8c 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -701,8 +701,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let local_id = self.var_local_id(var, for_guard);
         let source_info = self.source_info(span);
         self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
-        let region_scope = self.region_scope_tree.var_scope(var.local_id);
-        if schedule_drop {
+        // Altough there is almost always scope for given variable in corner cases
+        // like #92893 we might get variable with no scope.
+        if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) && schedule_drop{
             self.schedule_drop(span, region_scope, local_id, DropKind::Storage);
         }
         Place::from(local_id)
@@ -710,8 +711,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) {
         let local_id = self.var_local_id(var, for_guard);
-        let region_scope = self.region_scope_tree.var_scope(var.local_id);
-        self.schedule_drop(span, region_scope, local_id, DropKind::Value);
+        if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) {
+            self.schedule_drop(span, region_scope, local_id, DropKind::Value);
+        }
     }
 
     /// Visit all of the primary bindings in a patterns, that is, visit the
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index e584c9ad201f7..a4ae89ecada08 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
         self.expr_count += 1;
 
         if let PatKind::Binding(..) = pat.kind {
-            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
+            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
             let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
             self.record(ty, pat.hir_id, Some(scope), None, pat.span, false);
         }
diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs
new file mode 100644
index 0000000000000..d2bbb4f110114
--- /dev/null
+++ b/src/test/ui/mir/issue-92893.rs
@@ -0,0 +1,7 @@
+struct Bug<A = [(); (let a = (), 1).1]> {
+    //~^ `let` expressions are not supported here
+    //~^^ `let` expressions in this position are unstable [E0658]
+    a: A
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr
new file mode 100644
index 0000000000000..063b5d66feb45
--- /dev/null
+++ b/src/test/ui/mir/issue-92893.stderr
@@ -0,0 +1,20 @@
+error: `let` expressions are not supported here
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+   |                      ^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+   |                      ^^^^^^^^^^
+   |
+   = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
+   = help: add `#![feature(let_chains)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 72e86804ed2c3..6ed141fa4a5a6 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -59,7 +59,7 @@ pub(super) fn check<'tcx>(
                 if let Some(indexed_extent) = indexed_extent {
                     let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id);
                     let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);
-                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id);
+                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
                     if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {
                         return;
                     }
@@ -262,7 +262,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
                 match res {
                     Res::Local(hir_id) => {
                         let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
-                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id);
+                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id).unwrap();
                         if index_used_directly {
                             self.indexed_directly.insert(
                                 seqvar.segments[0].ident.name,
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index 1188258504461..1ab7f52110ce7 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -160,8 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
 
 fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
     let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
-    let first_scope = scope_tree.var_scope(first);
-    let second_scope = scope_tree.var_scope(second);
+    let first_scope = scope_tree.var_scope(first).unwrap();
+    let second_scope = scope_tree.var_scope(second).unwrap();
     scope_tree.is_subscope_of(second_scope, first_scope)
 }