From 5f43ea571a87d823860e0fb866571e084a7aa45e Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Thu, 13 Oct 2022 13:07:56 +0900
Subject: [PATCH 01/13] check if the self type is `ty::Float` before getting
 second substs

---
 .../src/traits/error_reporting/suggestions.rs | 22 +++---
 src/test/ui/traits/issue-102989.rs            | 18 +++++
 src/test/ui/traits/issue-102989.stderr        | 72 +++++++++++++++++++
 3 files changed, 99 insertions(+), 13 deletions(-)
 create mode 100644 src/test/ui/traits/issue-102989.rs
 create mode 100644 src/test/ui/traits/issue-102989.stderr

diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index fda6a2236b195..4431cf9f4436b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2937,19 +2937,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             ObligationCauseCode::BinOp { rhs_span: Some(span), is_lit, .. } if *is_lit => span,
             _ => return,
         };
-        match (
-            trait_ref.skip_binder().self_ty().kind(),
-            trait_ref.skip_binder().substs.type_at(1).kind(),
-        ) {
-            (ty::Float(_), ty::Infer(InferTy::IntVar(_))) => {
-                err.span_suggestion_verbose(
-                    rhs_span.shrink_to_hi(),
-                    "consider using a floating-point literal by writing it with `.0`",
-                    ".0",
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            _ => {}
+        if let ty::Float(_) = trait_ref.skip_binder().self_ty().kind()
+            && let ty::Infer(InferTy::IntVar(_)) = trait_ref.skip_binder().substs.type_at(1).kind()
+        {
+            err.span_suggestion_verbose(
+                rhs_span.shrink_to_hi(),
+                "consider using a floating-point literal by writing it with `.0`",
+                ".0",
+                Applicability::MaybeIncorrect,
+            );
         }
     }
 
diff --git a/src/test/ui/traits/issue-102989.rs b/src/test/ui/traits/issue-102989.rs
new file mode 100644
index 0000000000000..cd517a1c4ac87
--- /dev/null
+++ b/src/test/ui/traits/issue-102989.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Cinstrument-coverage
+//~^ ERROR can't find crate for `profiler_builtins`
+
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { } //~ ERROR found duplicate lang item `sized`
+
+fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+    //~^ ERROR `self` parameter is only allowed in associated functions
+    //~| ERROR cannot find type `Struct` in this scope
+    //~| ERROR mismatched types
+    let x = x << 1;
+    //~^ ERROR the size for values of type `{integer}` cannot be known at compilation time
+    //~| ERROR cannot find value `x` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-102989.stderr b/src/test/ui/traits/issue-102989.stderr
new file mode 100644
index 0000000000000..255fa6966efc9
--- /dev/null
+++ b/src/test/ui/traits/issue-102989.stderr
@@ -0,0 +1,72 @@
+error: `self` parameter is only allowed in associated functions
+  --> $DIR/issue-102989.rs:9:15
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |               ^^^^ not semantically valid as function parameter
+   |
+   = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0412]: cannot find type `Struct` in this scope
+  --> $DIR/issue-102989.rs:9:22
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                      ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-102989.rs:13:13
+   |
+LL |     let x = x << 1;
+   |             ^ help: a local variable with a similar name exists: `f`
+
+error: `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
+
+error[E0463]: can't find crate for `profiler_builtins`
+   |
+   = note: the compiler may have been built without the profiler runtime
+
+error[E0152]: found duplicate lang item `sized`
+  --> $DIR/issue-102989.rs:7:1
+   |
+LL | trait Sized { }
+   | ^^^^^^^^^^^
+   |
+   = note: the lang item is first defined in crate `core`.
+   = note: first definition in `core` loaded from $BUILD_DIR/aarch64-apple-darwin/stage1/lib/rustlib/aarch64-apple-darwin/lib/libcore-500f4c12402b1108.rlib
+   = note: second definition in the local crate (`issue_102989`)
+
+error: `#[panic_handler]` function required, but not found
+
+error: language item required, but not found: `eh_personality`
+   |
+   = note: this can occur when a binary crate with `#![no_std]` is compiled for a target where `eh_personality` is defined in the standard library
+   = help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
+
+error[E0277]: the size for values of type `{integer}` cannot be known at compilation time
+  --> $DIR/issue-102989.rs:13:15
+   |
+LL |     let x = x << 1;
+   |               ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `core::marker::Sized` is not implemented for `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-102989.rs:9:42
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |    ----------                            ^^^^ expected `&u32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+note: consider returning one of these bindings
+  --> $DIR/issue-102989.rs:9:30
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                              ^
+...
+LL |     let x = x << 1;
+   |         ^
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0152, E0277, E0308, E0412, E0425, E0463.
+For more information about an error, try `rustc --explain E0152`.

From 9b8aa653fd578fd9702c9194f0b7d2a20a927922 Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Thu, 13 Oct 2022 15:07:39 +0900
Subject: [PATCH 02/13] normalize stderr

---
 src/test/ui/traits/issue-102989.rs     |  3 ++-
 src/test/ui/traits/issue-102989.stderr | 16 ++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/test/ui/traits/issue-102989.rs b/src/test/ui/traits/issue-102989.rs
index cd517a1c4ac87..cb1e3271d26e8 100644
--- a/src/test/ui/traits/issue-102989.rs
+++ b/src/test/ui/traits/issue-102989.rs
@@ -1,5 +1,6 @@
+//~ ERROR can't find crate for `profiler_builtins`
 // compile-flags: -Cinstrument-coverage
-//~^ ERROR can't find crate for `profiler_builtins`
+// normalize-stderr-test "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib"
 
 #![no_core]
 #![feature(no_core, lang_items)]
diff --git a/src/test/ui/traits/issue-102989.stderr b/src/test/ui/traits/issue-102989.stderr
index 255fa6966efc9..efea2251a13f8 100644
--- a/src/test/ui/traits/issue-102989.stderr
+++ b/src/test/ui/traits/issue-102989.stderr
@@ -1,5 +1,5 @@
 error: `self` parameter is only allowed in associated functions
-  --> $DIR/issue-102989.rs:9:15
+  --> $DIR/issue-102989.rs:10:15
    |
 LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |               ^^^^ not semantically valid as function parameter
@@ -7,13 +7,13 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    = note: associated functions are those in `impl` or `trait` definitions
 
 error[E0412]: cannot find type `Struct` in this scope
-  --> $DIR/issue-102989.rs:9:22
+  --> $DIR/issue-102989.rs:10:22
    |
 LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                      ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-102989.rs:13:13
+  --> $DIR/issue-102989.rs:14:13
    |
 LL |     let x = x << 1;
    |             ^ help: a local variable with a similar name exists: `f`
@@ -25,13 +25,13 @@ error[E0463]: can't find crate for `profiler_builtins`
    = note: the compiler may have been built without the profiler runtime
 
 error[E0152]: found duplicate lang item `sized`
-  --> $DIR/issue-102989.rs:7:1
+  --> $DIR/issue-102989.rs:8:1
    |
 LL | trait Sized { }
    | ^^^^^^^^^^^
    |
    = note: the lang item is first defined in crate `core`.
-   = note: first definition in `core` loaded from $BUILD_DIR/aarch64-apple-darwin/stage1/lib/rustlib/aarch64-apple-darwin/lib/libcore-500f4c12402b1108.rlib
+   = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
    = note: second definition in the local crate (`issue_102989`)
 
 error: `#[panic_handler]` function required, but not found
@@ -42,7 +42,7 @@ error: language item required, but not found: `eh_personality`
    = help: you may be able to compile for a target that doesn't need `eh_personality`, specify a target with `--target` or in `.cargo/config`
 
 error[E0277]: the size for values of type `{integer}` cannot be known at compilation time
-  --> $DIR/issue-102989.rs:13:15
+  --> $DIR/issue-102989.rs:14:15
    |
 LL |     let x = x << 1;
    |               ^^ doesn't have a size known at compile-time
@@ -50,7 +50,7 @@ LL |     let x = x << 1;
    = help: the trait `core::marker::Sized` is not implemented for `{integer}`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-102989.rs:9:42
+  --> $DIR/issue-102989.rs:10:42
    |
 LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |    ----------                            ^^^^ expected `&u32`, found `()`
@@ -58,7 +58,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |    implicitly returns `()` as its body has no tail or `return` expression
    |
 note: consider returning one of these bindings
-  --> $DIR/issue-102989.rs:9:30
+  --> $DIR/issue-102989.rs:10:30
    |
 LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                              ^

From 3df9afcae781c2d9db5a2cb9acde9be5ae753285 Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Thu, 13 Oct 2022 07:33:34 +0000
Subject: [PATCH 03/13] rustdoc: don't ICE on `TyKind::Typeof`

---
 src/librustdoc/clean/mod.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8d556a962d9f5..7f82dfbd3d6ff 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1543,8 +1543,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
         }
         TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
         // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
-        TyKind::Infer | TyKind::Err => Infer,
-        TyKind::Typeof(..) => panic!("unimplemented type {:?}", ty.kind),
+        TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer,
     }
 }
 

From 097b6d3bafb1d61bfe8fd3f5e9d9acfd9ee2c702 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Wed, 12 Oct 2022 22:52:31 -0400
Subject: [PATCH 04/13] Add suggestion to the "missing native library" error

If we fail to locate a native library that we are linking with, it could
be the case the user entered a complete file name like `foo.lib` or
`libfoo.a` when we expect them to simply provide `foo`.

In this situation, we now detect that case and suggest the user only
provide the library name itself.
---
 .../locales/en-US/metadata.ftl                |  2 ++
 compiler/rustc_metadata/src/errors.rs         | 36 ++++++++++++++++++-
 compiler/rustc_metadata/src/native_libs.rs    |  2 +-
 .../suggest-libname-only-1.rs                 |  9 +++++
 .../suggest-libname-only-1.stderr             |  6 ++++
 .../suggest-libname-only-2.rs                 |  9 +++++
 .../suggest-libname-only-2.stderr             |  6 ++++
 7 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
 create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
 create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
 create mode 100644 src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr

diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
index d27100c56aff5..08e553d9f1589 100644
--- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl
@@ -165,6 +165,8 @@ metadata_failed_write_error =
 metadata_missing_native_library =
     could not find native static library `{$libname}`, perhaps an -L flag is missing?
 
+metadata_only_provide_library_name = only provide the library name `{$suggested_name}`, not the full filename
+
 metadata_failed_create_tempdir =
     couldn't create a temp dir: {$err}
 
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 1cd550644bf4d..dbfa22aaff074 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -372,7 +372,41 @@ pub struct FailedWriteError {
 #[derive(Diagnostic)]
 #[diag(metadata::missing_native_library)]
 pub struct MissingNativeLibrary<'a> {
-    pub libname: &'a str,
+    libname: &'a str,
+    #[subdiagnostic]
+    suggest_name: Option<SuggestLibraryName<'a>>,
+}
+
+impl<'a> MissingNativeLibrary<'a> {
+    pub fn new(libname: &'a str, verbatim: bool) -> Self {
+        // if it looks like the user has provided a complete filename rather just the bare lib name,
+        // then provide a note that they might want to try trimming the name
+        let suggested_name = if !verbatim {
+            if let Some(libname) = libname.strip_prefix("lib") && let Some(libname) = libname.strip_suffix(".a") {
+                // this is a unix style filename so trim prefix & suffix
+                Some(libname)
+            } else if let Some(libname) = libname.strip_suffix(".lib") {
+                // this is a Windows style filename so just trim the suffix
+                Some(libname)
+            } else {
+                None
+            }
+        } else {
+            None
+        };
+
+        Self {
+            libname,
+            suggest_name: suggested_name
+                .map(|suggested_name| SuggestLibraryName { suggested_name }),
+        }
+    }
+}
+
+#[derive(Subdiagnostic)]
+#[help(metadata::only_provide_library_name)]
+pub struct SuggestLibraryName<'a> {
+    suggested_name: &'a str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 9abb5c74895d0..676c67bad827f 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -52,7 +52,7 @@ pub fn find_native_static_library(
         }
     }
 
-    sess.emit_fatal(MissingNativeLibrary { libname: name });
+    sess.emit_fatal(MissingNativeLibrary::new(name, verbatim.unwrap_or(false)));
 }
 
 fn find_bundled_library(
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
new file mode 100644
index 0000000000000..abf988a7c1ed3
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `libfoo.a`
+// error-pattern: only provide the library name `foo`, not the full filename
+
+#[link(name = "libfoo.a", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
new file mode 100644
index 0000000000000..64d0a9077ed15
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `libfoo.a`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `foo`, not the full filename
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
new file mode 100644
index 0000000000000..dfa70e56db73c
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `bar.lib`
+// error-pattern: only provide the library name `bar`, not the full filename
+
+#[link(name = "bar.lib", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
new file mode 100644
index 0000000000000..e166af9ed8f03
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `bar.lib`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `bar`, not the full filename
+
+error: aborting due to previous error
+

From c47337e1150d1a214c04f9e5b532c80e8d7a89d0 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Thu, 13 Oct 2022 16:50:11 +0200
Subject: [PATCH 05/13] Update browser-ui-test version to 0.12.3

---
 .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index e96a87111cbbd..d61567cd134a3 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.12.2
\ No newline at end of file
+0.12.3
\ No newline at end of file

From 16cfd6cc8446215ec31dfd2e79a61e68fc8f276c Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Thu, 13 Oct 2022 16:51:04 +0200
Subject: [PATCH 06/13] Improve code for unsafe-fn rustdoc GUI test

---
 src/test/rustdoc-gui/unsafe-fn.goml | 53 ++++++++++++-----------------
 1 file changed, 22 insertions(+), 31 deletions(-)

diff --git a/src/test/rustdoc-gui/unsafe-fn.goml b/src/test/rustdoc-gui/unsafe-fn.goml
index 94f128db72e90..5e43b85fce084 100644
--- a/src/test/rustdoc-gui/unsafe-fn.goml
+++ b/src/test/rustdoc-gui/unsafe-fn.goml
@@ -1,37 +1,28 @@
+// Check position and color of the `<sup>` for unsafe elements.
 goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
-
-compare-elements-property: (
-	"//a[@title='test_docs::safe_fn fn']/..",
-	"//a[@title='test_docs::unsafe_fn fn']/..",
-	["clientHeight"]
-)
-
 // If the text isn't displayed, the browser doesn't compute color style correctly...
 show-text: true
 
-// Set the theme to dark.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(221, 221, 221)"
-})
-
-// Set the theme to ayu.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(197, 197, 197)"
-})
+compare-elements-property: (
+    "//a[@title='test_docs::safe_fn fn']/..",
+    "//a[@title='test_docs::unsafe_fn fn']/..",
+    ["clientHeight"]
+)
 
-// Set the theme to light.
-local-storage: {"rustdoc-theme": "light", "rustdoc-preferred-dark-theme": "light", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
+define-function: (
+    "sup-check",
+    // `theme` is the theme being tested.
+    // `color` is the expected color of the `<sup>` element.
+    (theme, color),
+    [
+        // Set the theme.
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        // We reload the page so the local storage settings are being used.
+        ("reload"),
+        ("assert-css", (".item-left sup", {"color": |color|})),
+    ],
+)
 
-assert-css: (".item-left sup", {
-	"color": "rgb(0, 0, 0)"
-})
+call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
+call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)"))
+call-function: ("sup-check", ("light", "rgb(0, 0, 0)"))

From 577d2cfbcc9b7c8981e7faaf62981d1b5b35b8a8 Mon Sep 17 00:00:00 2001
From: Maybe Waffle <waffle.lapkin@gmail.com>
Date: Thu, 13 Oct 2022 14:57:50 +0000
Subject: [PATCH 07/13] Add test for issue 102986

---
 src/test/rustdoc-ui/issue-102986.rs     |  4 ++++
 src/test/rustdoc-ui/issue-102986.stderr | 14 ++++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 src/test/rustdoc-ui/issue-102986.rs
 create mode 100644 src/test/rustdoc-ui/issue-102986.stderr

diff --git a/src/test/rustdoc-ui/issue-102986.rs b/src/test/rustdoc-ui/issue-102986.rs
new file mode 100644
index 0000000000000..001784ac28561
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.rs
@@ -0,0 +1,4 @@
+struct Struct {
+    y: (typeof("hey"),),
+    //~^ `typeof` is a reserved keyword but unimplemented
+}
diff --git a/src/test/rustdoc-ui/issue-102986.stderr b/src/test/rustdoc-ui/issue-102986.stderr
new file mode 100644
index 0000000000000..3a573726c9727
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.stderr
@@ -0,0 +1,14 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-102986.rs:2:9
+   |
+LL |     y: (typeof("hey"),),
+   |         ^^^^^^^^^^^^^ reserved keyword
+   |
+help: consider replacing `typeof(...)` with an actual type
+   |
+LL |     y: (&'static str,),
+   |         ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0516`.

From 6d609c5d6ed5339e4e235e0556a3656ab2697f4f Mon Sep 17 00:00:00 2001
From: nils <48135649+Nilstrieb@users.noreply.github.com>
Date: Thu, 13 Oct 2022 17:38:30 +0200
Subject: [PATCH 08/13] Add new bootstrap entrypoints to triagebot

---
 triagebot.toml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/triagebot.toml b/triagebot.toml
index 181fb1de93055..69bd49394099d 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -179,6 +179,8 @@ exclude_labels = [
 [autolabel."A-bootstrap"]
 trigger_files = [
     "x.py",
+    "x",
+    "x.ps1",
     "src/bootstrap",
     "src/tools/rust-installer",
 ]

From de0396c7180f8e36165c3fefb9325b0ec1bfb5a2 Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Thu, 13 Oct 2022 16:44:31 +0100
Subject: [PATCH 09/13] Ensure enum cast moves

---
 compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 35a00da8d38b2..3dafdcb788710 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -197,13 +197,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // create all the steps directly in MIR with operations all backends need to support anyway.
                 let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() {
                     let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx);
-                    let place = unpack!(block = this.as_place(block, source));
+                    let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not));
                     let discr = this.temp(discr_ty, source.span);
                     this.cfg.push_assign(
                         block,
                         source_info,
                         discr,
-                        Rvalue::Discriminant(place),
+                        Rvalue::Discriminant(temp.into()),
                     );
 
                     (Operand::Move(discr), discr_ty)

From d2d3d9433228adb35cfec0de8f3747879e38751f Mon Sep 17 00:00:00 2001
From: Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com>
Date: Thu, 13 Oct 2022 13:49:38 +0300
Subject: [PATCH 10/13] replace ReErased with fresh region vars in opaque types

---
 .../rustc_hir_analysis/src/check/check.rs     | 20 ++++--
 .../closure_parent_substs.rs                  | 65 +++++++++++++++++++
 .../closure_wf_outlives.rs                    | 65 +++++++++++++++++++
 .../closure_wf_outlives.stderr                | 64 ++++++++++++++++++
 4 files changed, 209 insertions(+), 5 deletions(-)
 create mode 100644 src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
 create mode 100644 src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
 create mode 100644 src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr

diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 7cee9779c5f39..c3583eeb430be 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -732,8 +732,6 @@ fn check_opaque_meets_bounds<'tcx>(
     span: Span,
     origin: &hir::OpaqueTyOrigin,
 ) {
-    let hidden_type = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs);
-
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
     let defining_use_anchor = match *origin {
         hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
@@ -748,14 +746,26 @@ fn check_opaque_meets_bounds<'tcx>(
     let ocx = ObligationCtxt::new(&infcx);
     let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
 
+    // `ReErased` regions appear in the "parent_substs" of closures/generators.
+    // We're ignoring them here and replacing them with fresh region variables.
+    // See tests in ui/type-alias-impl-trait/closure_{parent_substs,wf_outlives}.rs.
+    //
+    // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
+    // here rather than using ReErased.
+    let hidden_ty = tcx.bound_type_of(def_id.to_def_id()).subst(tcx, substs);
+    let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
+        ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
+        _ => re,
+    });
+
     let misc_cause = traits::ObligationCause::misc(span, hir_id);
 
-    match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) {
+    match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) {
         Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
         Err(ty_err) => {
             tcx.sess.delay_span_bug(
                 span,
-                &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
+                &format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
             );
         }
     }
@@ -764,7 +774,7 @@ fn check_opaque_meets_bounds<'tcx>(
     // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
     // hidden type is well formed even without those bounds.
     let predicate =
-        ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
+        ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())).to_predicate(tcx);
     ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
 
     // Check that all obligations are satisfied by the implementation's
diff --git a/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
new file mode 100644
index 0000000000000..475f4724ff28f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
@@ -0,0 +1,65 @@
+// When WF checking the hidden type in the ParamEnv of the opaque type,
+// one complication arises when the hidden type is a closure/generator:
+// the "parent_substs" of the type may reference lifetime parameters
+// not present in the opaque type.
+// These region parameters are not really useful in this check.
+// So here we ignore them and replace them with fresh region variables.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// Basic test
+mod test1 {
+    // Hidden type = Closure['_#0r]
+    type Opaque = impl Sized;
+
+    fn define<'a: 'a>() -> Opaque {
+        || {}
+    }
+}
+
+// the region vars cannot both be equal to `'static` or `'empty`
+mod test2 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, '_#0r, '_#1r]
+    // Constraints = [('_#0r: 'a), ('a: '_#1r)]
+    type Opaque<'a>
+    where
+        &'a (): Trait,
+    = impl Sized + 'a;
+
+    fn define<'a, 'x, 'y>() -> Opaque<'a>
+    where
+        &'a (): Trait,
+        'x: 'a,
+        'a: 'y,
+    {
+        || {}
+    }
+}
+
+// the region var cannot be equal to `'a` or `'b`
+mod test3 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, 'b, '_#0r]
+    // Constraints = [('_#0r: 'a), ('_#0r: 'b)]
+    type Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+    = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+        'x: 'a,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
new file mode 100644
index 0000000000000..53974dbb36bdf
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
@@ -0,0 +1,65 @@
+// If the hidden type is a closure, we require the "outlives" bounds that appear on the
+// defining site to also appear on the opaque type.
+//
+// It's not clear if this is the desired behavior but at least
+// it's consistent and has no back-compat risk.
+
+// check-fail
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// requires `'a: 'b` bound
+mod test1 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR lifetime bound not satisfied
+
+    fn define<'a, 'b>() -> Opaque<'a, 'b>
+    where
+        'a: 'b,
+    {
+        || {}
+    }
+}
+
+// Same as the above but through indirection `'x`
+mod test2 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR cannot infer an appropriate lifetime
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// fixed version of the above
+mod test2_fixed {
+    type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// requires `T: 'static`
+mod test3 {
+    type Opaque<T> = impl Sized;
+    //~^ ERROR the parameter type `T` may not live long enough
+
+    fn define<T>() -> Opaque<T>
+    where
+        T: 'static,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
new file mode 100644
index 0000000000000..ae6462bb62ce5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
@@ -0,0 +1,64 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/closure_wf_outlives.rs:14:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+note: but, the lifetime must be valid for the lifetime `'b` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/closure_wf_outlives.rs:54:22
+   |
+LL |     type Opaque<T> = impl Sized;
+   |                      ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/closure_wf_outlives.rs:59:12
+   |
+LL |         T: 'static,
+   |            ^^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL |     type Opaque<T: 'static> = impl Sized;
+   |                  +++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0310, E0478, E0495.
+For more information about an error, try `rustc --explain E0310`.

From f1452fc1c99bc6d126a096694b0f70d9fe4734b6 Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Thu, 13 Oct 2022 17:24:19 +0100
Subject: [PATCH 11/13] Add test for issue 102389

---
 src/test/ui/mir/issue-102389.rs     | 8 ++++++++
 src/test/ui/mir/issue-102389.stderr | 9 +++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 src/test/ui/mir/issue-102389.rs
 create mode 100644 src/test/ui/mir/issue-102389.stderr

diff --git a/src/test/ui/mir/issue-102389.rs b/src/test/ui/mir/issue-102389.rs
new file mode 100644
index 0000000000000..8b27d5e55743d
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.rs
@@ -0,0 +1,8 @@
+enum Enum { A, B, C }
+
+fn func(inbounds: &Enum, array: &[i16; 3]) -> i16 {
+    array[*inbounds as usize]
+    //~^ ERROR [E0507]
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-102389.stderr b/src/test/ui/mir/issue-102389.stderr
new file mode 100644
index 0000000000000..925dc258a4c3c
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of `*inbounds` which is behind a shared reference
+  --> $DIR/issue-102389.rs:4:11
+   |
+LL |     array[*inbounds as usize]
+   |           ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.

From 247da7b18de01886fb73a49f8b9ca59cfec16e64 Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Thu, 13 Oct 2022 17:24:27 +0100
Subject: [PATCH 12/13] Bless tests

---
 src/test/mir-opt/enum_cast.bar.mir_map.0.mir  | 10 +++--
 src/test/mir-opt/enum_cast.boo.mir_map.0.mir  | 10 +++--
 .../mir-opt/enum_cast.droppy.mir_map.0.mir    | 40 ++++++++++++-------
 src/test/mir-opt/enum_cast.foo.mir_map.0.mir  | 10 +++--
 4 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
index 8b12525b576ff..e58085f701ac2 100644
--- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn bar(_1: Bar) -> usize {
     debug bar => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Bar;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
index a77f4d06c239b..525c6234ed31d 100644
--- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn boo(_1: Boo) -> usize {
     debug boo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Boo;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
index ae3e71df8c6df..bb5faa48047a9 100644
--- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
@@ -4,8 +4,9 @@ fn droppy() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
     let _1: ();                          // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
     let _2: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
-    let mut _4: isize;                   // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
-    let _5: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+    let _4: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+    let mut _5: isize;                   // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+    let _6: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
     scope 1 {
         debug x => _2;                   // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14
         scope 2 {
@@ -16,7 +17,7 @@ fn droppy() -> () {
         }
     }
     scope 4 {
-        debug z => _5;                   // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
+        debug z => _6;                   // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
     }
 
     bb0: {
@@ -25,30 +26,41 @@ fn droppy() -> () {
         _2 = Droppy::C;                  // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26
         FakeRead(ForLet(None), _2);      // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
         StorageLive(_3);                 // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
-        _4 = discriminant(_2);           // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        _3 = move _4 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        StorageLive(_4);                 // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+        _4 = move _2;                    // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+        _5 = discriminant(_4);           // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
+    }
+
+    bb1: {
+        StorageDead(_4);                 // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
         FakeRead(ForLet(None), _3);      // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
         _1 = const ();                   // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
         StorageDead(_3);                 // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6
-        drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+        drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
     }
 
-    bb1: {
+    bb2: {
         StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
         StorageDead(_1);                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
-        StorageLive(_5);                 // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
-        _5 = Droppy::B;                  // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
-        FakeRead(ForLet(None), _5);      // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+        StorageLive(_6);                 // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+        _6 = Droppy::B;                  // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+        FakeRead(ForLet(None), _6);      // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
         _0 = const ();                   // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2
-        drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+        drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
     }
 
-    bb2: {
-        StorageDead(_5);                 // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+    bb3: {
+        StorageDead(_6);                 // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
         return;                          // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
     }
 
-    bb3 (cleanup): {
+    bb4 (cleanup): {
+        drop(_2) -> bb5;                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+    }
+
+    bb5 (cleanup): {
         resume;                          // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
index 9e44d9158e02f..a1d29a0b90320 100644
--- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn foo(_1: Foo) -> usize {
     debug foo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Foo;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }

From 4a25a49edfcca0392a9731df351f1a1229a6e662 Mon Sep 17 00:00:00 2001
From: Gary Guo <gary@garyguo.net>
Date: Thu, 13 Oct 2022 17:46:33 +0100
Subject: [PATCH 13/13] Fix test

---
 src/test/run-pass-valgrind/cast-enum-with-dtor.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
index f29bc50e84c4e..f7ef92df8fbec 100644
--- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
+++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
@@ -28,7 +28,7 @@ fn main() {
     {
         let e = E::C;
         assert_eq!(e as u32, 2);
-        assert_eq!(FLAG.load(Ordering::SeqCst), 0);
+        assert_eq!(FLAG.load(Ordering::SeqCst), 1);
     }
     assert_eq!(FLAG.load(Ordering::SeqCst), 1);
 }