about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-17 15:49:22 +0000
committerbors <bors@rust-lang.org>2021-09-17 15:49:22 +0000
commit207d9558d00dd5cc438a6418ba96912d396e2155 (patch)
treea1c61724745327620f23e9ce2b4ad491525e7d8b /src
parente0c38af27cb5f6f961809601b717d6afc3b190ee (diff)
parent101a88f95064b21a3de26f2d3e932408fa9e1c97 (diff)
Auto merge of #89047 - GuillaumeGomez:rollup-29gmr02, r=GuillaumeGomez
Rollup of 10 pull requests

Successful merges:

 - #86422 (Emit clearer diagnostics for parens around `for` loop heads)
 - #87460 (Point to closure when emitting 'cannot move out' for captured variable)
 - #87566 (Recover invalid assoc type bounds using `==`)
 - #88666 (Improve build command for compiler docs)
 - #88899 (Do not issue E0071 if a type error has already been reported)
 - #88949 (Fix handling of `hir::GenericArg::Infer` in `wrong_number_of_generic_args.rs`)
 - #88953 (Add chown functions to std::os::unix::fs to change the owner and group of files)
 - #88954 (Allow `panic!("{}", computed_str)` in const fn.)
 - #88964 (Add rustdoc version into the help popup)
 - #89012 (Suggest removing `#![feature]` for library features that have been stabilized)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/doc.rs63
-rw-r--r--src/librustdoc/html/render/write_shared.rs16
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css15
-rw-r--r--src/librustdoc/html/static/css/themes/ayu.css4
-rw-r--r--src/librustdoc/html/static/css/themes/dark.css4
-rw-r--r--src/librustdoc/html/static/css/themes/light.css4
-rw-r--r--src/librustdoc/html/static/js/main.js9
-rw-r--r--src/test/ui/borrowck/borrowck-in-static.stderr5
-rw-r--r--src/test/ui/borrowck/borrowck-move-by-capture.stderr21
-rw-r--r--src/test/ui/borrowck/issue-87456-point-to-closure.rs14
-rw-r--r--src/test/ui/borrowck/issue-87456-point-to-closure.stderr22
-rw-r--r--src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr14
-rw-r--r--src/test/ui/const-generics/issues/issue-87493.rs14
-rw-r--r--src/test/ui/const-generics/issues/issue-87493.stderr28
-rw-r--r--src/test/ui/consts/const-eval/const_panic.rs8
-rw-r--r--src/test/ui/consts/const-eval/const_panic.stderr38
-rw-r--r--src/test/ui/consts/const-eval/const_panic_2021.rs16
-rw-r--r--src/test/ui/consts/const-eval/const_panic_2021.stderr58
-rw-r--r--src/test/ui/issues/issue-4335.stderr5
-rw-r--r--src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr5
-rw-r--r--src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr5
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.rs2
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.stderr15
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr14
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr554
-rw-r--r--src/test/ui/suggestions/option-content-move2.stderr27
-rw-r--r--src/test/ui/typeck/issue-88844.rs14
-rw-r--r--src/test/ui/typeck/issue-88844.stderr12
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr20
29 files changed, 748 insertions, 278 deletions
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index b7478d83955..af3774b7c75 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -537,7 +537,7 @@ impl Step for Rustc {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.krate("rustc-main").default_condition(builder.config.docs)
+        run.krate("rustc-main").path("compiler").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -553,9 +553,24 @@ impl Step for Rustc {
     fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
+        let mut is_explicit_request = false;
         builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
 
-        if !builder.config.compiler_docs {
+        let paths = builder
+            .paths
+            .iter()
+            .map(components_simplified)
+            .filter_map(|path| {
+                if path.get(0) == Some(&"compiler") {
+                    is_explicit_request = true;
+                    path.get(1).map(|p| p.to_owned())
+                } else {
+                    None
+                }
+            })
+            .collect::<Vec<_>>();
+
+        if !builder.config.compiler_docs && !is_explicit_request {
             builder.info("\tskipping - compiler/librustdoc docs disabled");
             return;
         }
@@ -604,26 +619,54 @@ impl Step for Rustc {
         cargo.rustdocflag("--extern-html-root-url");
         cargo.rustdocflag("ena=https://docs.rs/ena/latest/");
 
-        // Find dependencies for top level crates.
         let mut compiler_crates = HashSet::new();
-        for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
-            compiler_crates.extend(
-                builder
-                    .in_tree_crates(root_crate, Some(target))
-                    .into_iter()
-                    .map(|krate| krate.name),
-            );
+
+        if paths.is_empty() {
+            // Find dependencies for top level crates.
+            for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
+                compiler_crates.extend(
+                    builder
+                        .in_tree_crates(root_crate, Some(target))
+                        .into_iter()
+                        .map(|krate| krate.name),
+                );
+            }
+        } else {
+            for root_crate in paths {
+                if !builder.src.join("compiler").join(&root_crate).exists() {
+                    builder.info(&format!(
+                        "\tskipping - compiler/{} (unknown compiler crate)",
+                        root_crate
+                    ));
+                } else {
+                    compiler_crates.extend(
+                        builder
+                            .in_tree_crates(root_crate, Some(target))
+                            .into_iter()
+                            .map(|krate| krate.name),
+                    );
+                }
+            }
         }
 
+        let mut to_open = None;
         for krate in &compiler_crates {
             // Create all crate output directories first to make sure rustdoc uses
             // relative links.
             // FIXME: Cargo should probably do this itself.
             t!(fs::create_dir_all(out_dir.join(krate)));
             cargo.arg("-p").arg(krate);
+            if to_open.is_none() {
+                to_open = Some(krate);
+            }
         }
 
         builder.run(&mut cargo.into());
+        // Let's open the first crate documentation page:
+        if let Some(krate) = to_open {
+            let index = out.join(krate).join("index.html");
+            open(builder, &index);
+        }
     }
 }
 
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 1dd0917699b..c1a83ad5820 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -268,10 +268,18 @@ pub(super) fn write_shared(
     // Maybe we can change the representation to move this out of main.js?
     write_minify(
         "main.js",
-        static_files::MAIN_JS.replace(
-            "/* INSERT THEMES HERE */",
-            &format!(" = {}", serde_json::to_string(&themes).unwrap()),
-        ),
+        static_files::MAIN_JS
+            .replace(
+                "/* INSERT THEMES HERE */",
+                &format!(" = {}", serde_json::to_string(&themes).unwrap()),
+            )
+            .replace(
+                "/* INSERT RUSTDOC_VERSION HERE */",
+                &format!(
+                    "rustdoc {}",
+                    rustc_interface::util::version_str().unwrap_or("unknown version")
+                ),
+            ),
         cx,
         options,
     )?;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 2d4bfc62af6..eb7cc9309f4 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -928,15 +928,24 @@ body.blur > :not(#help) {
 	display: block;
 	margin-right: 0.5rem;
 }
-#help > div > span {
+#help span.top, #help span.bottom {
 	text-align: center;
 	display: block;
-	margin: 10px 0;
 	font-size: 18px;
-	border-bottom: 1px solid #ccc;
+
+}
+#help span.top {
+	text-align: center;
+	display: block;
+	margin: 10px 0;
+	border-bottom: 1px solid;
 	padding-bottom: 4px;
 	margin-bottom: 6px;
 }
+#help span.bottom {
+	clear: both;
+	border-top: 1px solid;
+}
 #help dd { margin: 5px 35px; }
 #help .infos { padding-left: 0; }
 #help h1, #help h2 { margin-top: 0; }
diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css
index eada8f4a04d..c79801e8308 100644
--- a/src/librustdoc/html/static/css/themes/ayu.css
+++ b/src/librustdoc/html/static/css/themes/ayu.css
@@ -286,8 +286,8 @@ details.undocumented > summary::before {
 	border-radius: 4px;
 }
 
-#help > div > span {
-	border-bottom-color: #5c6773;
+#help span.bottom, #help span.top {
+	border-color: #5c6773;
 }
 
 .since {
diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css
index d9348be6994..d2e54070acd 100644
--- a/src/librustdoc/html/static/css/themes/dark.css
+++ b/src/librustdoc/html/static/css/themes/dark.css
@@ -242,8 +242,8 @@ details.undocumented > summary::before {
 	border-color: #bfbfbf;
 }
 
-#help > div > span {
-	border-bottom-color: #bfbfbf;
+#help span.bottom, #help span.top {
+	border-color: #bfbfbf;
 }
 
 #help dt {
diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css
index 0ffe5929ea5..25d810560c1 100644
--- a/src/librustdoc/html/static/css/themes/light.css
+++ b/src/librustdoc/html/static/css/themes/light.css
@@ -232,8 +232,8 @@ details.undocumented > summary::before {
 	border-color: #bfbfbf;
 }
 
-#help > div > span {
-	border-bottom-color: #bfbfbf;
+#help span.bottom, #help span.top {
+	border-color: #bfbfbf;
 }
 
 .since {
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 1eebd392564..e396fd9d288 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -911,6 +911,7 @@ function hideThemeButtonState() {
         });
 
         var book_info = document.createElement("span");
+        book_info.className = "top";
         book_info.innerHTML = "You can find more information in \
             <a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>.";
 
@@ -961,6 +962,14 @@ function hideThemeButtonState() {
         container.appendChild(div_shortcuts);
         container.appendChild(div_infos);
 
+        var rustdoc_version = document.createElement("span");
+        rustdoc_version.className = "bottom";
+        var rustdoc_version_code = document.createElement("code");
+        rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */";
+        rustdoc_version.appendChild(rustdoc_version_code);
+
+        container.appendChild(rustdoc_version);
+
         popup.appendChild(container);
         insertAfter(popup, searchState.outputElement());
         // So that it's only built once and then it'll do nothing when called!
diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr
index f73c787346d..30e74c5ec95 100644
--- a/src/test/ui/borrowck/borrowck-in-static.stderr
+++ b/src/test/ui/borrowck/borrowck-in-static.stderr
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |     let x = Box::new(0);
    |         - captured outer variable
 LL |     Box::new(|| x)
-   |                 ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |              ---^
+   |              |  |
+   |              |  move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |              captured by this `Fn` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-move-by-capture.stderr b/src/test/ui/borrowck/borrowck-move-by-capture.stderr
index 628f206e0a8..05489cf18e7 100644
--- a/src/test/ui/borrowck/borrowck-move-by-capture.stderr
+++ b/src/test/ui/borrowck/borrowck-move-by-capture.stderr
@@ -1,15 +1,18 @@
 error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-move-by-capture.rs:9:29
    |
-LL |     let bar: Box<_> = box 3;
-   |         --- captured outer variable
-LL |     let _g = to_fn_mut(|| {
-LL |         let _h = to_fn_once(move || -> isize { *bar });
-   |                             ^^^^^^^^^^^^^^^^   ----
-   |                             |                  |
-   |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
-   |                             |                  move occurs due to use in closure
-   |                             move out of `bar` occurs here
+LL |       let bar: Box<_> = box 3;
+   |           --- captured outer variable
+LL |       let _g = to_fn_mut(|| {
+   |  ________________________-
+LL | |         let _h = to_fn_once(move || -> isize { *bar });
+   | |                             ^^^^^^^^^^^^^^^^   ----
+   | |                             |                  |
+   | |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+   | |                             |                  move occurs due to use in closure
+   | |                             move out of `bar` occurs here
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-87456-point-to-closure.rs b/src/test/ui/borrowck/issue-87456-point-to-closure.rs
new file mode 100644
index 00000000000..9fc12ba7490
--- /dev/null
+++ b/src/test/ui/borrowck/issue-87456-point-to-closure.rs
@@ -0,0 +1,14 @@
+// Regression test for #87456.
+
+fn take_mut(_val: impl FnMut()) {}
+
+fn main() {
+    let val = String::new();
+    //~^ NOTE: captured outer variable
+    take_mut(|| {
+    //~^ NOTE: captured by this `FnMut` closure
+        let _foo: String = val;
+        //~^ ERROR: cannot move out of `val`, a captured variable in an `FnMut` closure [E0507]
+        //~| NOTE: move occurs because
+    })
+}
diff --git a/src/test/ui/borrowck/issue-87456-point-to-closure.stderr b/src/test/ui/borrowck/issue-87456-point-to-closure.stderr
new file mode 100644
index 00000000000..fd38ad7bb0a
--- /dev/null
+++ b/src/test/ui/borrowck/issue-87456-point-to-closure.stderr
@@ -0,0 +1,22 @@
+error[E0507]: cannot move out of `val`, a captured variable in an `FnMut` closure
+  --> $DIR/issue-87456-point-to-closure.rs:10:28
+   |
+LL |       let val = String::new();
+   |           --- captured outer variable
+LL |
+LL |       take_mut(|| {
+   |  ______________-
+LL | |
+LL | |         let _foo: String = val;
+   | |                            ^^^
+   | |                            |
+   | |                            move occurs because `val` has type `String`, which does not implement the `Copy` trait
+   | |                            help: consider borrowing here: `&val`
+LL | |
+LL | |
+LL | |     })
+   | |_____- captured by this `FnMut` closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
index dbba33f0183..1663ce81d6c 100644
--- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
+++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
@@ -1,11 +1,15 @@
 error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:11:9
    |
-LL |     let y = vec![format!("World")];
-   |         - captured outer variable
-LL |     call(|| {
-LL |         y.into_iter();
-   |         ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+LL |       let y = vec![format!("World")];
+   |           - captured outer variable
+LL |       call(|| {
+   |  __________-
+LL | |         y.into_iter();
+   | |         ^ move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+LL | |
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/issues/issue-87493.rs b/src/test/ui/const-generics/issues/issue-87493.rs
new file mode 100644
index 00000000000..d8599ab22a3
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-87493.rs
@@ -0,0 +1,14 @@
+pub trait MyTrait {
+    type Assoc;
+}
+
+pub fn foo<S, T>(_s: S, _t: T)
+where
+    S: MyTrait,
+    T: MyTrait<Assoc == S::Assoc>,
+    //~^ ERROR: expected one of `,` or `>`, found `==`
+    //~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-87493.stderr b/src/test/ui/const-generics/issues/issue-87493.stderr
new file mode 100644
index 00000000000..8f92eeaffd1
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-87493.stderr
@@ -0,0 +1,28 @@
+error: expected one of `,` or `>`, found `==`
+  --> $DIR/issue-87493.rs:8:22
+   |
+LL |     T: MyTrait<Assoc == S::Assoc>,
+   |                      ^^ expected one of `,` or `>`
+   |
+help: if you meant to use an associated type binding, replace `==` with `=`
+   |
+LL |     T: MyTrait<Assoc = S::Assoc>,
+   |                      ~
+
+error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/issue-87493.rs:8:8
+   |
+LL |     T: MyTrait<Assoc == S::Assoc>,
+   |        ^^^^^^^------------------- help: remove these generics
+   |        |
+   |        expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/issue-87493.rs:1:11
+   |
+LL | pub trait MyTrait {
+   |           ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/consts/const-eval/const_panic.rs b/src/test/ui/consts/const-eval/const_panic.rs
index e4455d86a14..100faded079 100644
--- a/src/test/ui/consts/const-eval/const_panic.rs
+++ b/src/test/ui/consts/const-eval/const_panic.rs
@@ -15,10 +15,13 @@ const Y: () = std::unreachable!();
 
 const X: () = std::unimplemented!();
 //~^ ERROR evaluation of constant value failed
-//
+
 const W: () = std::panic!(MSG);
 //~^ ERROR evaluation of constant value failed
 
+const W2: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
 const Z_CORE: () = core::panic!("cheese");
 //~^ ERROR evaluation of constant value failed
 
@@ -33,3 +36,6 @@ const X_CORE: () = core::unimplemented!();
 
 const W_CORE: () = core::panic!(MSG);
 //~^ ERROR evaluation of constant value failed
+
+const W2_CORE: () = core::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr
index c0c749ede56..e98e4a506c0 100644
--- a/src/test/ui/consts/const-eval/const_panic.stderr
+++ b/src/test/ui/consts/const-eval/const_panic.stderr
@@ -39,45 +39,61 @@ LL | const W: () = std::panic!(MSG);
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:22:20
+  --> $DIR/const_panic.rs:22:16
+   |
+LL | const W2: () = std::panic!("{}", MSG);
+   |                ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:22:16
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic.rs:25:20
    |
 LL | const Z_CORE: () = core::panic!("cheese");
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:22:20
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:25:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:25:21
+  --> $DIR/const_panic.rs:28:21
    |
 LL | const Z2_CORE: () = core::panic!();
-   |                     ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:25:21
+   |                     ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:28:21
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:28:20
+  --> $DIR/const_panic.rs:31:20
    |
 LL | const Y_CORE: () = core::unreachable!();
-   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:28:20
+   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:31:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:31:20
+  --> $DIR/const_panic.rs:34:20
    |
 LL | const X_CORE: () = core::unimplemented!();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:31:20
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:34:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic.rs:34:20
+  --> $DIR/const_panic.rs:37:20
    |
 LL | const W_CORE: () = core::panic!(MSG);
-   |                    ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:34:20
+   |                    ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:37:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic.rs:40:21
+   |
+LL | const W2_CORE: () = core::panic!("{}", MSG);
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:40:21
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/const_panic_2021.rs b/src/test/ui/consts/const-eval/const_panic_2021.rs
index daef34cd6a3..9b8652a776e 100644
--- a/src/test/ui/consts/const-eval/const_panic_2021.rs
+++ b/src/test/ui/consts/const-eval/const_panic_2021.rs
@@ -2,6 +2,8 @@
 #![feature(const_panic)]
 #![crate_type = "lib"]
 
+const MSG: &str = "hello";
+
 const A: () = std::panic!("blåhaj");
 //~^ ERROR evaluation of constant value failed
 
@@ -14,14 +16,20 @@ const C: () = std::unreachable!();
 const D: () = std::unimplemented!();
 //~^ ERROR evaluation of constant value failed
 
-const E: () = core::panic!("shark");
+const E: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
+const A_CORE: () = core::panic!("shark");
+//~^ ERROR evaluation of constant value failed
+
+const B_CORE: () = core::panic!();
 //~^ ERROR evaluation of constant value failed
 
-const F: () = core::panic!();
+const C_CORE: () = core::unreachable!();
 //~^ ERROR evaluation of constant value failed
 
-const G: () = core::unreachable!();
+const D_CORE: () = core::unimplemented!();
 //~^ ERROR evaluation of constant value failed
 
-const H: () = core::unimplemented!();
+const E_CORE: () = core::panic!("{}", MSG);
 //~^ ERROR evaluation of constant value failed
diff --git a/src/test/ui/consts/const-eval/const_panic_2021.stderr b/src/test/ui/consts/const-eval/const_panic_2021.stderr
index c1bdab3693d..9eb241ae8e5 100644
--- a/src/test/ui/consts/const-eval/const_panic_2021.stderr
+++ b/src/test/ui/consts/const-eval/const_panic_2021.stderr
@@ -1,67 +1,83 @@
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:5:15
+  --> $DIR/const_panic_2021.rs:7:15
    |
 LL | const A: () = std::panic!("blåhaj");
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:5:15
+   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:7:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:8:15
+  --> $DIR/const_panic_2021.rs:10:15
    |
 LL | const B: () = std::panic!();
-   |               ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:8:15
+   |               ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:10:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:11:15
+  --> $DIR/const_panic_2021.rs:13:15
    |
 LL | const C: () = std::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:11:15
+   |               ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:13:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:14:15
+  --> $DIR/const_panic_2021.rs:16:15
    |
 LL | const D: () = std::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:14:15
+   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:16:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:17:15
+  --> $DIR/const_panic_2021.rs:19:15
    |
-LL | const E: () = core::panic!("shark");
-   |               ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:17:15
+LL | const E: () = std::panic!("{}", MSG);
+   |               ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:19:15
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:20:15
+  --> $DIR/const_panic_2021.rs:22:20
    |
-LL | const F: () = core::panic!();
-   |               ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:20:15
+LL | const A_CORE: () = core::panic!("shark");
+   |                    ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:22:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:23:15
+  --> $DIR/const_panic_2021.rs:25:20
    |
-LL | const G: () = core::unreachable!();
-   |               ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:23:15
+LL | const B_CORE: () = core::panic!();
+   |                    ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:25:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic_2021.rs:28:20
+   |
+LL | const C_CORE: () = core::unreachable!();
+   |                    ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:28:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0080]: evaluation of constant value failed
-  --> $DIR/const_panic_2021.rs:26:15
+  --> $DIR/const_panic_2021.rs:31:20
    |
-LL | const H: () = core::unimplemented!();
-   |               ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:26:15
+LL | const D_CORE: () = core::unimplemented!();
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:31:20
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 8 previous errors
+error[E0080]: evaluation of constant value failed
+  --> $DIR/const_panic_2021.rs:34:20
+   |
+LL | const E_CORE: () = core::panic!("{}", MSG);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:34:20
+   |
+   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/issues/issue-4335.stderr b/src/test/ui/issues/issue-4335.stderr
index f187969ff4e..fa3b58e1279 100644
--- a/src/test/ui/issues/issue-4335.stderr
+++ b/src/test/ui/issues/issue-4335.stderr
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `*v`, as `v` is a captured variable in an `FnMu
 LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
    |             - captured outer variable
 LL |     id(Box::new(|| *v))
-   |                    ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+   |                 ---^^
+   |                 |  |
+   |                 |  move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+   |                 captured by this `FnMut` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
index 9427ba546a9..e12af2d4527 100644
--- a/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
+++ b/src/test/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
 LL |     let i = box 3;
    |         - captured outer variable
 LL |     let _f = to_fn(|| test(i));
-   |                            ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |                    --------^-
+   |                    |       |
+   |                    |       move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |                    captured by this `Fn` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
index 67115a5ccdd..c9324f0422c 100644
--- a/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
+++ b/src/test/ui/nll/issue-52663-span-decl-captured-variable.stderr
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
 LL |        let x = (vec![22], vec![44]);
    |            - captured outer variable
 LL |        expect_fn(|| drop(x.0));
-   |                          ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |                  --------^^^-
+   |                  |       |
+   |                  |       move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |                  captured by this `Fn` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.rs b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
index 779e1646344..8080dbc332a 100644
--- a/src/test/ui/parser/recover-for-loop-parens-around-head.rs
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
@@ -9,7 +9,7 @@ fn main() {
 
     for ( elem in vec ) {
         //~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in`
-        //~| ERROR unexpected closing `)`
+        //~| ERROR unexpected parenthesis surrounding `for` loop head
         const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
     }
 }
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
index e97cf544ac2..21991348327 100644
--- a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
@@ -4,14 +4,17 @@ error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
 LL |     for ( elem in vec ) {
    |                ^^ expected one of `)`, `,`, `@`, or `|`
 
-error: unexpected closing `)`
-  --> $DIR/recover-for-loop-parens-around-head.rs:10:23
+error: unexpected parenthesis surrounding `for` loop head
+  --> $DIR/recover-for-loop-parens-around-head.rs:10:9
    |
 LL |     for ( elem in vec ) {
-   |         --------------^
-   |         |
-   |         opening `(`
-   |         help: remove parenthesis in `for` loop: `elem in vec`
+   |         ^             ^
+   |
+help: remove parenthesis in `for` loop
+   |
+LL -     for ( elem in vec ) {
+LL +     for  elem in vec  {
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/recover-for-loop-parens-around-head.rs:13:38
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index ab1fa2a4d87..0f630abd148 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -29,11 +29,17 @@ LL |     f.f.call_mut(())
 error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
    |
-LL |     let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
-   |         ----- captured outer variable
+LL |       let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+   |           ----- captured outer variable
 ...
-LL |         foo(f);
-   |             ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
+LL |       f(Box::new(|a| {
+   |  ________________-
+LL | |
+LL | |         foo(f);
+   | |             ^ move occurs because `f` has type `[closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 54:6]`, which does not implement the `Copy` trait
+LL | |
+LL | |     }), 3);
+   | |_____- captured by this `FnMut` closure
 
 error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:55:16
diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
index c50cbcde855..fb1055c9c30 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
+++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.stderr
@@ -1,281 +1,487 @@
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:28:21
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(_t) = x;
-   |               --    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+   | |               --    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL | |
+LL | |
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:32:34
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         if let Either::One(_t) = e { }
-   |                            --    ^ help: consider borrowing here: `&e`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+LL | |
+LL | |         if let Either::One(_t) = e { }
+   | |                            --    ^ help: consider borrowing here: `&e`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:36:37
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         while let Either::One(_t) = e { }
-   |                               --    ^ help: consider borrowing here: `&e`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(_t) = e { }
+   | |                               --    ^ help: consider borrowing here: `&e`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:40:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
-...
-LL |             Either::One(_t)
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t)
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:47:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
-...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |             Either::One(_t) => (),
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t) => (),
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:56:25
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(mut _t) = x;
-   |               ------    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         let X(mut _t) = x;
+   | |               ------    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:60:38
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^ help: consider borrowing here: `&em`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         if let Either::One(mut _t) = em { }
+   | |                            ------    ^^ help: consider borrowing here: `&em`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:64:41
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^ help: consider borrowing here: `&em`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(mut _t) = em { }
+   | |                               ------    ^^ help: consider borrowing here: `&em`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:68:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t)
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t)
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure
   --> $DIR/move-into-closure.rs:75:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
-...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fn(|| {
+   |  ________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:95:21
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(_t) = x;
-   |               --    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+   | |               --    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL | |
+LL | |
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:99:34
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         if let Either::One(_t) = e { }
-   |                            --    ^ help: consider borrowing here: `&e`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+LL | |
+LL | |         if let Either::One(_t) = e { }
+   | |                            --    ^ help: consider borrowing here: `&e`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:103:37
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         while let Either::One(_t) = e { }
-   |                               --    ^ help: consider borrowing here: `&e`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(_t) = e { }
+   | |                               --    ^ help: consider borrowing here: `&e`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:107:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
-...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |             Either::One(_t)
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t)
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:114:15
    |
-LL |     let e = Either::One(X(Y));
-   |         - captured outer variable
+LL |       let e = Either::One(X(Y));
+   |           - captured outer variable
 ...
-LL |         match e {
-   |               ^ help: consider borrowing here: `&e`
-...
-LL |             Either::One(_t) => (),
-   |                         --
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match e {
+   | |               ^ help: consider borrowing here: `&e`
+...  |
+LL | |             Either::One(_t) => (),
+   | |                         --
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:123:25
    |
-LL |     let x = X(Y);
-   |         - captured outer variable
+LL |       let x = X(Y);
+   |           - captured outer variable
 ...
-LL |         let X(mut _t) = x;
-   |               ------    ^ help: consider borrowing here: `&x`
-   |               |
-   |               data moved here
-   |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         let X(mut _t) = x;
+   | |               ------    ^ help: consider borrowing here: `&x`
+   | |               |
+   | |               data moved here
+   | |               move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:127:38
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         if let Either::One(mut _t) = em { }
-   |                            ------    ^^ help: consider borrowing here: `&em`
-   |                            |
-   |                            data moved here
-   |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         if let Either::One(mut _t) = em { }
+   | |                            ------    ^^ help: consider borrowing here: `&em`
+   | |                            |
+   | |                            data moved here
+   | |                            move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:131:41
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         while let Either::One(mut _t) = em { }
-   |                               ------    ^^ help: consider borrowing here: `&em`
-   |                               |
-   |                               data moved here
-   |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         while let Either::One(mut _t) = em { }
+   | |                               ------    ^^ help: consider borrowing here: `&em`
+   | |                               |
+   | |                               data moved here
+   | |                               move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:135:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t)
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t)
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:142:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
-...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure
   --> $DIR/move-into-closure.rs:150:15
    |
-LL |     let mut em = Either::One(X(Y));
-   |         ------ captured outer variable
-...
-LL |         match em {
-   |               ^^ help: consider borrowing here: `&em`
+LL |       let mut em = Either::One(X(Y));
+   |           ------ captured outer variable
 ...
-LL |             Either::One(mut _t) => (),
-   |                         ------
-   |                         |
-   |                         data moved here
-   |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+LL |       consume_fnmut(|| {
+   |  ___________________-
+LL | |         let X(_t) = x;
+LL | |
+LL | |
+...  |
+LL | |         match em {
+   | |               ^^ help: consider borrowing here: `&em`
+...  |
+LL | |             Either::One(mut _t) => (),
+   | |                         ------
+   | |                         |
+   | |                         data moved here
+   | |                         move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+...  |
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to 21 previous errors
 
diff --git a/src/test/ui/suggestions/option-content-move2.stderr b/src/test/ui/suggestions/option-content-move2.stderr
index cfbee1518cd..a0ce7d05b4d 100644
--- a/src/test/ui/suggestions/option-content-move2.stderr
+++ b/src/test/ui/suggestions/option-content-move2.stderr
@@ -1,17 +1,22 @@
 error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
   --> $DIR/option-content-move2.rs:9:9
    |
-LL |     let mut var = None;
-   |         ------- captured outer variable
-...
-LL |         move || {
-   |         ^^^^^^^ move out of `var` occurs here
-LL |
-LL |             var = Some(NotCopyable);
-   |             ---
-   |             |
-   |             move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
-   |             move occurs due to use in closure
+LL |       let mut var = None;
+   |           ------- captured outer variable
+LL |       func(|| {
+   |  __________-
+LL | |         // Shouldn't suggest `move ||.as_ref()` here
+LL | |         move || {
+   | |         ^^^^^^^ move out of `var` occurs here
+LL | |
+LL | |             var = Some(NotCopyable);
+   | |             ---
+   | |             |
+   | |             move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+   | |             move occurs due to use in closure
+LL | |         }
+LL | |     });
+   | |_____- captured by this `FnMut` closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/issue-88844.rs b/src/test/ui/typeck/issue-88844.rs
new file mode 100644
index 00000000000..116c75aabdb
--- /dev/null
+++ b/src/test/ui/typeck/issue-88844.rs
@@ -0,0 +1,14 @@
+// Regression test for #88844.
+
+struct Struct { value: i32 }
+//~^ NOTE: similarly named struct `Struct` defined here
+
+impl Stuct {
+//~^ ERROR: cannot find type `Stuct` in this scope [E0412]
+//~| HELP: a struct with a similar name exists
+    fn new() -> Self {
+        Self { value: 42 }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/issue-88844.stderr b/src/test/ui/typeck/issue-88844.stderr
new file mode 100644
index 00000000000..90bba90be34
--- /dev/null
+++ b/src/test/ui/typeck/issue-88844.stderr
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `Stuct` in this scope
+  --> $DIR/issue-88844.rs:6:6
+   |
+LL | struct Struct { value: i32 }
+   | ------------- similarly named struct `Struct` defined here
+...
+LL | impl Stuct {
+   |      ^^^^^ help: a struct with a similar name exists: `Struct`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
index f8c90176ff1..482d3e44fe4 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
@@ -4,7 +4,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(|| drop(x));
-   |                               ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       --------^-
+   |                       |       |
+   |                       |       move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:19:35
@@ -12,7 +15,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(|| drop(x));
-   |                                   ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           --------^-
+   |                           |       |
+   |                           |       move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           captured by this `FnMut` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:28:36
@@ -20,7 +26,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn(move || drop(x));
-   |                                    ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       -------------^-
+   |                       |            |
+   |                       |            move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       captured by this `Fn` closure
 
 error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:32:40
@@ -28,7 +37,10 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
 LL |         let x = Box::new(0);
    |             - captured outer variable
 LL |         let f = to_fn_mut(move || drop(x));
-   |                                        ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           -------------^-
+   |                           |            |
+   |                           |            move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           captured by this `FnMut` closure
 
 error: aborting due to 4 previous errors