about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-07-20 11:29:37 +0530
committerGitHub <noreply@github.com>2022-07-20 11:29:37 +0530
commit97c9f16a45c0ebda9facf38180549f896a81cf32 (patch)
tree0306e1c0fdfbb53af615bbc8c40191fc85e8c6fe /src/test
parentf426146460c5446bb41ac0b677bbfe5b6ff502ba (diff)
parentb0a81904ce58cd226bc5015b2d9ef97671880fbd (diff)
downloadrust-97c9f16a45c0ebda9facf38180549f896a81cf32.tar.gz
rust-97c9f16a45c0ebda9facf38180549f896a81cf32.zip
Rollup merge of #98784 - compiler-errors:forgot-to-return-binding, r=estebank
Suggest returning local on "expected `ty`, found `()`" due to expr-less block

Putting this up for _initial_ review. Notably, this doesn't consider if the value has possibly been moved, or whether the type is `Copy`. It also provides a structured suggestion if there's one "preferred" binding that matches the type (i.e. one binding in the block or its parent), otherwise it just points them out if there's fewer than 4 of them.

Fixes #98177

r? `@estebank`
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr18
-rw-r--r--src/test/ui/liveness/liveness-forgot-ret.stderr5
-rw-r--r--src/test/ui/parser/issues/issue-33413.stderr5
-rw-r--r--src/test/ui/suggestions/return-bindings-multi.rs9
-rw-r--r--src/test/ui/suggestions/return-bindings-multi.stderr34
-rw-r--r--src/test/ui/suggestions/return-bindings.fixed23
-rw-r--r--src/test/ui/suggestions/return-bindings.rs21
-rw-r--r--src/test/ui/suggestions/return-bindings.stderr48
8 files changed, 154 insertions, 9 deletions
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index e5887689690..ada6e357aea 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -18,6 +18,14 @@ LL | |             break 0u8;
 LL | |         };
    | |_________- enclosing `async` block
 
+error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
+  --> $DIR/async-block-control-flow-static-semantics.rs:26:39
+   |
+LL |     let _: &dyn Future<Output = ()> = &block;
+   |                                       ^^^^^^ expected `()`, found `u8`
+   |
+   = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
+
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:21:58
    |
@@ -32,7 +40,7 @@ LL | | }
    | |_^ expected `u8`, found `()`
 
 error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
-  --> $DIR/async-block-control-flow-static-semantics.rs:26:39
+  --> $DIR/async-block-control-flow-static-semantics.rs:17:39
    |
 LL |     let _: &dyn Future<Output = ()> = &block;
    |                                       ^^^^^^ expected `()`, found `u8`
@@ -47,14 +55,6 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
-error[E0271]: type mismatch resolving `<impl Future<Output = u8> as Future>::Output == ()`
-  --> $DIR/async-block-control-flow-static-semantics.rs:17:39
-   |
-LL |     let _: &dyn Future<Output = ()> = &block;
-   |                                       ^^^^^^ expected `()`, found `u8`
-   |
-   = note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
-
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:47:44
    |
diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr
index 95070322bdd..ddbdbdb0fd0 100644
--- a/src/test/ui/liveness/liveness-forgot-ret.stderr
+++ b/src/test/ui/liveness/liveness-forgot-ret.stderr
@@ -5,6 +5,11 @@ LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; }
    |    -              ^^^^^ expected `isize`, found `()`
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `a`
+   |
+LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; a }
+   |                                                           +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issues/issue-33413.stderr b/src/test/ui/parser/issues/issue-33413.stderr
index ac320f095a2..b7250f3b0b5 100644
--- a/src/test/ui/parser/issues/issue-33413.stderr
+++ b/src/test/ui/parser/issues/issue-33413.stderr
@@ -11,6 +11,11 @@ LL |     fn f(*, a: u8) -> u8 {}
    |        -              ^^ expected `u8`, found `()`
    |        |
    |        implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `a`
+   |
+LL |     fn f(*, a: u8) -> u8 { a }
+   |                            +
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/return-bindings-multi.rs b/src/test/ui/suggestions/return-bindings-multi.rs
new file mode 100644
index 00000000000..8c3bd641e97
--- /dev/null
+++ b/src/test/ui/suggestions/return-bindings-multi.rs
@@ -0,0 +1,9 @@
+fn a(i: i32) -> i32 {
+    //~^ ERROR mismatched types
+    let j = 2i32;
+}
+
+fn b(i: i32, j: i32) -> i32 {}
+//~^ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-bindings-multi.stderr b/src/test/ui/suggestions/return-bindings-multi.stderr
new file mode 100644
index 00000000000..738e3f2f4be
--- /dev/null
+++ b/src/test/ui/suggestions/return-bindings-multi.stderr
@@ -0,0 +1,34 @@
+error[E0308]: mismatched types
+  --> $DIR/return-bindings-multi.rs:1:17
+   |
+LL | fn a(i: i32) -> i32 {
+   |    -            ^^^ expected `i32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+note: consider returning one of these bindings
+  --> $DIR/return-bindings-multi.rs:1:6
+   |
+LL | fn a(i: i32) -> i32 {
+   |      ^
+LL |
+LL |     let j = 2i32;
+   |         ^
+
+error[E0308]: mismatched types
+  --> $DIR/return-bindings-multi.rs:6:25
+   |
+LL | fn b(i: i32, j: i32) -> i32 {}
+   |    -                    ^^^ expected `i32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+note: consider returning one of these bindings
+  --> $DIR/return-bindings-multi.rs:6:6
+   |
+LL | fn b(i: i32, j: i32) -> i32 {}
+   |      ^       ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/return-bindings.fixed b/src/test/ui/suggestions/return-bindings.fixed
new file mode 100644
index 00000000000..4fabc411abc
--- /dev/null
+++ b/src/test/ui/suggestions/return-bindings.fixed
@@ -0,0 +1,23 @@
+// run-rustfix
+
+#![allow(unused)]
+
+fn a(i: i32) -> i32 { i }
+//~^ ERROR mismatched types
+
+fn b(opt_str: Option<String>) {
+    let s: String = if let Some(s) = opt_str {
+        s
+    //~^ ERROR mismatched types
+    } else {
+        String::new()
+    };
+}
+
+fn c() -> Option<i32> {
+    //~^ ERROR mismatched types
+    let x = Some(1);
+    x
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-bindings.rs b/src/test/ui/suggestions/return-bindings.rs
new file mode 100644
index 00000000000..d05b4ba27d6
--- /dev/null
+++ b/src/test/ui/suggestions/return-bindings.rs
@@ -0,0 +1,21 @@
+// run-rustfix
+
+#![allow(unused)]
+
+fn a(i: i32) -> i32 {}
+//~^ ERROR mismatched types
+
+fn b(opt_str: Option<String>) {
+    let s: String = if let Some(s) = opt_str {
+        //~^ ERROR mismatched types
+    } else {
+        String::new()
+    };
+}
+
+fn c() -> Option<i32> {
+    //~^ ERROR mismatched types
+    let x = Some(1);
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-bindings.stderr b/src/test/ui/suggestions/return-bindings.stderr
new file mode 100644
index 00000000000..e5d49255005
--- /dev/null
+++ b/src/test/ui/suggestions/return-bindings.stderr
@@ -0,0 +1,48 @@
+error[E0308]: mismatched types
+  --> $DIR/return-bindings.rs:5:17
+   |
+LL | fn a(i: i32) -> i32 {}
+   |    -            ^^^ expected `i32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `i`
+   |
+LL | fn a(i: i32) -> i32 { i }
+   |                       +
+
+error[E0308]: mismatched types
+  --> $DIR/return-bindings.rs:9:46
+   |
+LL |       let s: String = if let Some(s) = opt_str {
+   |  ______________________________________________^
+LL | |
+LL | |     } else {
+   | |_____^ expected struct `String`, found `()`
+   |
+help: consider returning the local binding `s`
+   |
+LL ~     let s: String = if let Some(s) = opt_str {
+LL +         s
+LL ~
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/return-bindings.rs:16:11
+   |
+LL | fn c() -> Option<i32> {
+   |    -      ^^^^^^^^^^^ expected enum `Option`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note:   expected enum `Option<i32>`
+           found unit type `()`
+help: consider returning the local binding `x`
+   |
+LL ~     let x = Some(1);
+LL +     x
+   |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.