about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-08-15 00:32:05 +0000
committerbors <bors@rust-lang.org>2019-08-15 00:32:05 +0000
commit9e9a136fcec5eb78f09a14dfd072a51ae2550269 (patch)
treeb193fe082d78583740df368de6f546ca35890cbb /src/test
parent082cf2f9d136166cd1d552d3fb5abb1c46c99a14 (diff)
parent78cd9d1fd5cd59fbab62325b1bcb4bb21c2cb30a (diff)
downloadrust-9e9a136fcec5eb78f09a14dfd072a51ae2550269.tar.gz
rust-9e9a136fcec5eb78f09a14dfd072a51ae2550269.zip
Auto merge of #63575 - Centril:rollup-anlv9g5, r=Centril
Rollup of 11 pull requests

Successful merges:

 - #62984 (Add lint for excess trailing semicolons)
 - #63075 (Miri: Check that a ptr is aligned and inbounds already when evaluating `*`)
 - #63490 (libsyntax: cleanup and refactor `pat.rs`)
 - #63507 (When needing type annotations in local bindings, account for impl Trait and closures)
 - #63509 (Point at the right enclosing scope when using `await` in non-async fn)
 - #63528 (syntax: Remove `DummyResult::expr_only`)
 - #63537 (expand: Unimplement `MutVisitor` on `MacroExpander`)
 - #63542 (Add NodeId for Arm, Field and FieldPat)
 - #63543 (Merge Variant and Variant_)
 - #63560 (move test that shouldn't be in test/run-pass/)
 - #63570 (Adjust tracking issues for `MaybeUninit<T>` gates)

Failed merges:

r? @ghost
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/async-await/issues/non-async-enclosing-span.rs12
-rw-r--r--src/test/ui/async-await/issues/non-async-enclosing-span.stderr11
-rw-r--r--src/test/ui/block-expr-precedence.stderr8
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.rs7
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.stderr29
-rw-r--r--src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr5
-rw-r--r--src/test/ui/error-codes/E0282.stderr5
-rw-r--r--src/test/ui/for/for-loop-unconstrained-element-type.stderr5
-rw-r--r--src/test/ui/generator/niche-in-generator.rs (renamed from src/test/run-pass/generator/niche-in-generator.rs)2
-rw-r--r--src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs18
-rw-r--r--src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr19
-rw-r--r--src/test/ui/inference/cannot-infer-async.rs16
-rw-r--r--src/test/ui/inference/cannot-infer-async.stderr11
-rw-r--r--src/test/ui/inference/cannot-infer-closure.rs6
-rw-r--r--src/test/ui/inference/cannot-infer-closure.stderr13
-rw-r--r--src/test/ui/issues/issue-18159.stderr5
-rw-r--r--src/test/ui/match/match-unresolved-one-arm.stderr5
-rw-r--r--src/test/ui/parser/doc-before-semi.rs2
-rw-r--r--src/test/ui/parser/doc-before-semi.stderr8
-rw-r--r--src/test/ui/proc-macro/span-preservation.rs2
-rw-r--r--src/test/ui/proc-macro/span-preservation.stderr2
-rw-r--r--src/test/ui/suggestions/suggest-box.fixed8
-rw-r--r--src/test/ui/suggestions/suggest-box.rs8
-rw-r--r--src/test/ui/suggestions/suggest-box.stderr24
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-1.rs3
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-1.stderr13
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-2.rs3
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-2.stderr13
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-3.rs3
-rw-r--r--src/test/ui/suggestions/suggest-closure-return-type-3.stderr13
30 files changed, 245 insertions, 34 deletions
diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.rs b/src/test/ui/async-await/issues/non-async-enclosing-span.rs
new file mode 100644
index 00000000000..838911d9b6e
--- /dev/null
+++ b/src/test/ui/async-await/issues/non-async-enclosing-span.rs
@@ -0,0 +1,12 @@
+// edition:2018
+#![feature(async_await)]
+
+async fn do_the_thing() -> u8 {
+    8
+}
+// #63398: point at the enclosing scope and not the previously seen closure
+fn main() {  //~ NOTE this is not `async`
+    let x = move || {};
+    let y = do_the_thing().await; //~ ERROR `await` is only allowed inside `async` functions
+    //~^ NOTE only allowed inside `async` functions and blocks
+}
diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr
new file mode 100644
index 00000000000..f492c1a8045
--- /dev/null
+++ b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr
@@ -0,0 +1,11 @@
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/non-async-enclosing-span.rs:10:13
+   |
+LL | fn main() {
+   |    ---- this is not `async`
+LL |     let x = move || {};
+LL |     let y = do_the_thing().await;
+   |             ^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/block-expr-precedence.stderr b/src/test/ui/block-expr-precedence.stderr
new file mode 100644
index 00000000000..1307b5d6ddd
--- /dev/null
+++ b/src/test/ui/block-expr-precedence.stderr
@@ -0,0 +1,8 @@
+warning: unnecessary trailing semicolons
+  --> $DIR/block-expr-precedence.rs:60:21
+   |
+LL |   if (true) { 12; };;; -num;
+   |                     ^^ help: remove these semicolons
+   |
+   = note: `#[warn(redundant_semicolon)]` on by default
+
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index bcbb4358aec..431ff356ade 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -11,10 +11,11 @@ const NON_NULL_PTR: NonNull<u8> = unsafe { mem::transmute(&1) };
 const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
 //~^ ERROR it is undefined behavior to use this value
 
+#[deny(const_err)] // this triggers a `const_err` so validation does not even happen
 const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
-//~^ ERROR it is undefined behavior to use this value
-    let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
-    let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
+    let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+    // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
+    let out_of_bounds_ptr = &ptr[255]; //~ ERROR any use of this value will cause an error
     mem::transmute(out_of_bounds_ptr)
 } };
 
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr
index 2f9423fed35..7b3c97e5fbf 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr
@@ -6,21 +6,26 @@ LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:14:1
+error: any use of this value will cause an error
+  --> $DIR/ub-nonnull.rs:18:29
    |
 LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
-LL | |
-LL | |     let ptr: &(u8, u8, u8) = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
-LL | |     let out_of_bounds_ptr = &ptr.2; // use address-of-field for pointer arithmetic
+LL | |     let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+LL | |     // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
+LL | |     let out_of_bounds_ptr = &ptr[255];
+   | |                             ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 6 which has size 1
 LL | |     mem::transmute(out_of_bounds_ptr)
 LL | | } };
-   | |____^ type validation failed: encountered a potentially NULL pointer, but expected something that cannot possibly fail to be greater or equal to 1
+   | |____-
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+note: lint level defined here
+  --> $DIR/ub-nonnull.rs:14:8
+   |
+LL | #[deny(const_err)] // this triggers a `const_err` so validation does not even happen
+   |        ^^^^^^^^^
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:21:1
+  --> $DIR/ub-nonnull.rs:22:1
    |
 LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
@@ -28,7 +33,7 @@ LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:23:1
+  --> $DIR/ub-nonnull.rs:24:1
    |
 LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
@@ -36,7 +41,7 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:30:1
+  --> $DIR/ub-nonnull.rs:31:1
    |
 LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1
@@ -44,7 +49,7 @@ LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:38:1
+  --> $DIR/ub-nonnull.rs:39:1
    |
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
@@ -52,7 +57,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:44:1
+  --> $DIR/ub-nonnull.rs:45:1
    |
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
index f1c93d54637..f5edbe2a3af 100644
--- a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
+++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
@@ -28,7 +28,10 @@ error: expected `{`, found `;`
 LL |     if not  // lack of braces is [sic]
    |     -- this `if` statement has a condition, but no block
 LL |         println!("Then when?");
-   |                               ^ expected `{`
+   |                               ^
+   |                               |
+   |                               expected `{`
+   |                               help: try placing this code inside a block: `{ ; }`
 
 error: unexpected `2` after identifier
   --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24
diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr
index 3a5040eb6da..0f610a5e42f 100644
--- a/src/test/ui/error-codes/E0282.stderr
+++ b/src/test/ui/error-codes/E0282.stderr
@@ -2,10 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/E0282.rs:2:9
    |
 LL |     let x = "hello".chars().rev().collect();
-   |         ^
-   |         |
-   |         cannot infer type
-   |         consider giving `x` a type
+   |         ^ consider giving `x` a type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/for/for-loop-unconstrained-element-type.stderr b/src/test/ui/for/for-loop-unconstrained-element-type.stderr
index 02fdb808da4..0672014a929 100644
--- a/src/test/ui/for/for-loop-unconstrained-element-type.stderr
+++ b/src/test/ui/for/for-loop-unconstrained-element-type.stderr
@@ -2,10 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/for-loop-unconstrained-element-type.rs:8:14
    |
 LL |     for i in Vec::new() { }
-   |              ^^^^^^^^^^
-   |              |
-   |              cannot infer type
-   |              the element type for this iterator is not specified
+   |              ^^^^^^^^^^ the element type for this iterator is not specified
 
 error: aborting due to previous error
 
diff --git a/src/test/run-pass/generator/niche-in-generator.rs b/src/test/ui/generator/niche-in-generator.rs
index 9a644ed44a6..42bee81f524 100644
--- a/src/test/run-pass/generator/niche-in-generator.rs
+++ b/src/test/ui/generator/niche-in-generator.rs
@@ -1,5 +1,7 @@
 // Test that niche finding works with captured generator upvars.
 
+// run-pass
+
 #![feature(generators)]
 
 use std::mem::size_of_val;
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
new file mode 100644
index 00000000000..30ed5050433
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
@@ -0,0 +1,18 @@
+// edition:2018
+#![feature(async_await)]
+#![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
+
+use std::io::Error;
+
+fn make_unit() -> Result<(), Error> {
+    Ok(())
+}
+
+fn main() {
+    let fut = async {
+        make_unit()?; //~ ERROR type annotations needed
+
+        Ok(())
+    };
+}
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
new file mode 100644
index 00000000000..67a834a2e95
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
@@ -0,0 +1,19 @@
+warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
+  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:3:12
+   |
+LL | #![feature(impl_trait_in_bindings)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0282]: type annotations needed for `impl std::future::Future`
+  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:14:9
+   |
+LL |     let fut = async {
+   |         --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified
+LL |         make_unit()?;
+   |         ^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/cannot-infer-async.rs b/src/test/ui/inference/cannot-infer-async.rs
new file mode 100644
index 00000000000..edc64276e7c
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-async.rs
@@ -0,0 +1,16 @@
+// edition:2018
+#![feature(async_await)]
+
+use std::io::Error;
+
+fn make_unit() -> Result<(), Error> {
+    Ok(())
+}
+
+fn main() {
+    let fut = async {
+        make_unit()?; //~ ERROR type annotations needed
+
+        Ok(())
+    };
+}
diff --git a/src/test/ui/inference/cannot-infer-async.stderr b/src/test/ui/inference/cannot-infer-async.stderr
new file mode 100644
index 00000000000..36608a11bb7
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-async.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/cannot-infer-async.rs:12:9
+   |
+LL |     let fut = async {
+   |         --- consider giving `fut` a type
+LL |         make_unit()?;
+   |         ^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/cannot-infer-closure.rs b/src/test/ui/inference/cannot-infer-closure.rs
new file mode 100644
index 00000000000..8f48483c254
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-closure.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let x = |a: (), b: ()| {
+        Err(a)?; //~ ERROR type annotations needed for the closure
+        Ok(b)
+    };
+}
diff --git a/src/test/ui/inference/cannot-infer-closure.stderr b/src/test/ui/inference/cannot-infer-closure.stderr
new file mode 100644
index 00000000000..5f30b5d993c
--- /dev/null
+++ b/src/test/ui/inference/cannot-infer-closure.stderr
@@ -0,0 +1,13 @@
+error[E0282]: type annotations needed for the closure `fn((), ()) -> std::result::Result<(), _>`
+  --> $DIR/cannot-infer-closure.rs:3:9
+   |
+LL |         Err(a)?;
+   |         ^^^^^^^ cannot infer type
+help: give this closure an explicit return type without `_` placeholders
+   |
+LL |     let x = |a: (), b: ()| -> std::result::Result<(), _> {
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-18159.stderr b/src/test/ui/issues/issue-18159.stderr
index 6048344125c..9b890be3c78 100644
--- a/src/test/ui/issues/issue-18159.stderr
+++ b/src/test/ui/issues/issue-18159.stderr
@@ -2,10 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/issue-18159.rs:2:9
    |
 LL |     let x;
-   |         ^
-   |         |
-   |         cannot infer type
-   |         consider giving `x` a type
+   |         ^ consider giving `x` a type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr
index ad8569b4802..77df9921b75 100644
--- a/src/test/ui/match/match-unresolved-one-arm.stderr
+++ b/src/test/ui/match/match-unresolved-one-arm.stderr
@@ -2,10 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/match-unresolved-one-arm.rs:4:9
    |
 LL |     let x = match () {
-   |         ^
-   |         |
-   |         cannot infer type
-   |         consider giving `x` a type
+   |         ^ consider giving `x` a type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs
index 405a7e1e2a3..c3f478fe420 100644
--- a/src/test/ui/parser/doc-before-semi.rs
+++ b/src/test/ui/parser/doc-before-semi.rs
@@ -3,4 +3,6 @@ fn main() {
     //~^ ERROR found a documentation comment that doesn't document anything
     //~| HELP maybe a comment was intended
     ;
+    //~^ WARNING unnecessary trailing semicolon
+    //~| HELP remove this semicolon
 }
diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr
index e6bade18d0a..b9ac30b09b2 100644
--- a/src/test/ui/parser/doc-before-semi.stderr
+++ b/src/test/ui/parser/doc-before-semi.stderr
@@ -6,6 +6,14 @@ LL |     /// hi
    |
    = help: doc comments must come before what they document, maybe a comment was intended with `//`?
 
+warning: unnecessary trailing semicolon
+  --> $DIR/doc-before-semi.rs:5:5
+   |
+LL |     ;
+   |     ^ help: remove this semicolon
+   |
+   = note: `#[warn(redundant_semicolon)]` on by default
+
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0585`.
diff --git a/src/test/ui/proc-macro/span-preservation.rs b/src/test/ui/proc-macro/span-preservation.rs
index 0a82d28e9e5..55835cb88f4 100644
--- a/src/test/ui/proc-macro/span-preservation.rs
+++ b/src/test/ui/proc-macro/span-preservation.rs
@@ -9,7 +9,7 @@ extern crate test_macros;
 
 #[recollect_attr]
 fn a() {
-    let x: usize = "hello";;;;; //~ ERROR mismatched types
+    let x: usize = "hello"; //~ ERROR mismatched types
 }
 
 #[recollect_attr]
diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr
index cf03deee7e4..0290f4b2cc9 100644
--- a/src/test/ui/proc-macro/span-preservation.stderr
+++ b/src/test/ui/proc-macro/span-preservation.stderr
@@ -6,7 +6,7 @@ error[E0308]: mismatched types
 error[E0308]: mismatched types
   --> $DIR/span-preservation.rs:12:20
    |
-LL |     let x: usize = "hello";;;;;
+LL |     let x: usize = "hello";
    |                    ^^^^^^^ expected usize, found reference
    |
    = note: expected type `usize`
diff --git a/src/test/ui/suggestions/suggest-box.fixed b/src/test/ui/suggestions/suggest-box.fixed
new file mode 100644
index 00000000000..3de02cd0bd4
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-box.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| { //~ ERROR mismatched types
+        Err(())?;
+        Ok(())
+    });
+}
diff --git a/src/test/ui/suggestions/suggest-box.rs b/src/test/ui/suggestions/suggest-box.rs
new file mode 100644
index 00000000000..e680a61db3b
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-box.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+fn main() {
+    let _x: Box<dyn Fn() -> Result<(), ()>> = || { //~ ERROR mismatched types
+        Err(())?;
+        Ok(())
+    };
+}
diff --git a/src/test/ui/suggestions/suggest-box.stderr b/src/test/ui/suggestions/suggest-box.stderr
new file mode 100644
index 00000000000..50c106d63a0
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-box.stderr
@@ -0,0 +1,24 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-box.rs:4:47
+   |
+LL |       let _x: Box<dyn Fn() -> Result<(), ()>> = || {
+   |  _______________________________________________^
+LL | |         Err(())?;
+LL | |         Ok(())
+LL | |     };
+   | |_____^ expected struct `std::boxed::Box`, found closure
+   |
+   = note: expected type `std::boxed::Box<dyn std::ops::Fn() -> std::result::Result<(), ()>>`
+              found type `[closure@$DIR/suggest-box.rs:4:47: 7:6]`
+   = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     let _x: Box<dyn Fn() -> Result<(), ()>> = Box::new(|| {
+LL |         Err(())?;
+LL |         Ok(())
+LL |     });
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-1.rs b/src/test/ui/suggestions/suggest-closure-return-type-1.rs
new file mode 100644
index 00000000000..910f273b972
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-1.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _v = || -> _ { [] }; //~ ERROR type annotations needed for the closure
+}
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-1.stderr b/src/test/ui/suggestions/suggest-closure-return-type-1.stderr
new file mode 100644
index 00000000000..de2d29f1270
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-1.stderr
@@ -0,0 +1,13 @@
+error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
+  --> $DIR/suggest-closure-return-type-1.rs:2:24
+   |
+LL |     let _v = || -> _ { [] };
+   |                        ^^ cannot infer type
+help: give this closure an explicit return type without `_` placeholders
+   |
+LL |     let _v = || -> [_; 0] { [] };
+   |                    ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-2.rs b/src/test/ui/suggestions/suggest-closure-return-type-2.rs
new file mode 100644
index 00000000000..6955b37ad97
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-2.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _v = || { [] }; //~ ERROR type annotations needed for the closure
+}
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-2.stderr b/src/test/ui/suggestions/suggest-closure-return-type-2.stderr
new file mode 100644
index 00000000000..9dbd822fbb5
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-2.stderr
@@ -0,0 +1,13 @@
+error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
+  --> $DIR/suggest-closure-return-type-2.rs:2:19
+   |
+LL |     let _v = || { [] };
+   |                   ^^ cannot infer type
+help: give this closure an explicit return type without `_` placeholders
+   |
+LL |     let _v = || -> [_; 0] { [] };
+   |                 ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-3.rs b/src/test/ui/suggestions/suggest-closure-return-type-3.rs
new file mode 100644
index 00000000000..ec6c094027e
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-3.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _v = || []; //~ ERROR type annotations needed for the closure
+}
diff --git a/src/test/ui/suggestions/suggest-closure-return-type-3.stderr b/src/test/ui/suggestions/suggest-closure-return-type-3.stderr
new file mode 100644
index 00000000000..ad0d4e41f78
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-closure-return-type-3.stderr
@@ -0,0 +1,13 @@
+error[E0282]: type annotations needed for the closure `fn() -> [_; 0]`
+  --> $DIR/suggest-closure-return-type-3.rs:2:17
+   |
+LL |     let _v = || [];
+   |                 ^^ cannot infer type
+help: give this closure an explicit return type without `_` placeholders
+   |
+LL |     let _v = || -> [_; 0] { [] };
+   |                 ^^^^^^^^^^^    ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.