summaryrefslogtreecommitdiffstats
path: root/src/test/ui/return
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/return')
-rw-r--r--src/test/ui/return/issue-82612-return-mutable-reference.rs24
-rw-r--r--src/test/ui/return/issue-82612-return-mutable-reference.stderr28
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.rs41
-rw-r--r--src/test/ui/return/issue-86188-return-not-in-fn-body.stderr52
-rw-r--r--src/test/ui/return/return-from-diverging.rs8
-rw-r--r--src/test/ui/return/return-from-diverging.stderr14
-rw-r--r--src/test/ui/return/return-impl-trait-bad.rs31
-rw-r--r--src/test/ui/return/return-impl-trait-bad.stderr59
-rw-r--r--src/test/ui/return/return-impl-trait.fixed30
-rw-r--r--src/test/ui/return/return-impl-trait.rs30
-rw-r--r--src/test/ui/return/return-impl-trait.stderr34
-rw-r--r--src/test/ui/return/return-match-array-const.rs19
-rw-r--r--src/test/ui/return/return-match-array-const.stderr56
-rw-r--r--src/test/ui/return/return-type.rs14
-rw-r--r--src/test/ui/return/return-type.stderr20
-rw-r--r--src/test/ui/return/return-unit-from-diverging.rs9
-rw-r--r--src/test/ui/return/return-unit-from-diverging.stderr11
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.rs32
-rw-r--r--src/test/ui/return/tail-expr-as-potential-return.stderr37
19 files changed, 549 insertions, 0 deletions
diff --git a/src/test/ui/return/issue-82612-return-mutable-reference.rs b/src/test/ui/return/issue-82612-return-mutable-reference.rs
new file mode 100644
index 000000000..db0d08ddb
--- /dev/null
+++ b/src/test/ui/return/issue-82612-return-mutable-reference.rs
@@ -0,0 +1,24 @@
+// Regression test for #82612.
+
+use std::marker::PhantomData;
+
+pub trait SparseSetIndex {
+ fn sparse_set_index(&self) -> usize;
+}
+pub struct SparseArray<I, V = I> {
+ values: Vec<Option<V>>,
+ marker: PhantomData<I>,
+}
+
+impl<I: SparseSetIndex, V> SparseArray<I, V> {
+ pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
+ let index = index.sparse_set_index();
+ if index < self.values.len() {
+ let value = unsafe { self.values.get_unchecked_mut(index) };
+ value.get_or_insert_with(func) //~ ERROR mismatched types
+ }
+ unsafe { self.values.get_unchecked_mut(index).as_mut().unwrap() }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/return/issue-82612-return-mutable-reference.stderr b/src/test/ui/return/issue-82612-return-mutable-reference.stderr
new file mode 100644
index 000000000..eb2322d51
--- /dev/null
+++ b/src/test/ui/return/issue-82612-return-mutable-reference.stderr
@@ -0,0 +1,28 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-82612-return-mutable-reference.rs:18:13
+ |
+LL | / if index < self.values.len() {
+LL | | let value = unsafe { self.values.get_unchecked_mut(index) };
+LL | | value.get_or_insert_with(func)
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&mut V`
+LL | | }
+ | |_________- expected this to be `()`
+ |
+ = note: expected unit type `()`
+ found mutable reference `&mut V`
+help: consider using a semicolon here
+ |
+LL | value.get_or_insert_with(func);
+ | +
+help: consider using a semicolon here
+ |
+LL | };
+ | +
+help: you might have meant to return this value
+ |
+LL | return value.get_or_insert_with(func);
+ | ++++++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.rs b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs
new file mode 100644
index 000000000..4f076fa06
--- /dev/null
+++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.rs
@@ -0,0 +1,41 @@
+// Due to a compiler bug, if a return occurs outside of a function body
+// (e.g. in an AnonConst body), the return value expression would not be
+// type-checked, leading to an ICE. This test checks that the ICE no
+// longer happens, and that an appropriate error message is issued that
+// also explains why the return is considered "outside of a function body"
+// if it seems to be inside one, as in the main function below.
+
+const C: [(); 42] = {
+ [(); return || {
+ //~^ ERROR: return statement outside of function body [E0572]
+ let tx;
+ }]
+};
+
+struct S {}
+trait Tr {
+ fn foo();
+ fn bar() {
+ //~^ NOTE: ...not the enclosing function body
+ [(); return];
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+ }
+}
+impl Tr for S {
+ fn foo() {
+ //~^ NOTE: ...not the enclosing function body
+ [(); return];
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+ }
+}
+
+fn main() {
+//~^ NOTE: ...not the enclosing function body
+ [(); return || {
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+ let tx;
+ }];
+}
diff --git a/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
new file mode 100644
index 000000000..d7eeb3a72
--- /dev/null
+++ b/src/test/ui/return/issue-86188-return-not-in-fn-body.stderr
@@ -0,0 +1,52 @@
+error[E0572]: return statement outside of function body
+ --> $DIR/issue-86188-return-not-in-fn-body.rs:9:10
+ |
+LL | [(); return || {
+ | __________^
+LL | |
+LL | | let tx;
+LL | | }]
+ | |_____^
+
+error[E0572]: return statement outside of function body
+ --> $DIR/issue-86188-return-not-in-fn-body.rs:20:14
+ |
+LL | / fn bar() {
+LL | |
+LL | | [(); return];
+ | | ^^^^^^ the return is part of this body...
+LL | |
+LL | |
+LL | | }
+ | |_____- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+ --> $DIR/issue-86188-return-not-in-fn-body.rs:28:14
+ |
+LL | / fn foo() {
+LL | |
+LL | | [(); return];
+ | | ^^^^^^ the return is part of this body...
+LL | |
+LL | |
+LL | | }
+ | |_____- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+ --> $DIR/issue-86188-return-not-in-fn-body.rs:36:10
+ |
+LL | / fn main() {
+LL | |
+LL | | [(); return || {
+ | |__________^
+LL | ||
+LL | ||
+LL | || let tx;
+LL | || }];
+ | ||_____^ the return is part of this body...
+LL | | }
+ | |_- ...not the enclosing function body
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0572`.
diff --git a/src/test/ui/return/return-from-diverging.rs b/src/test/ui/return/return-from-diverging.rs
new file mode 100644
index 000000000..2ee48e7bc
--- /dev/null
+++ b/src/test/ui/return/return-from-diverging.rs
@@ -0,0 +1,8 @@
+// Test that return another type in place of ! raises a type mismatch.
+
+fn fail() -> ! {
+ return "wow"; //~ ERROR mismatched types
+}
+
+fn main() {
+}
diff --git a/src/test/ui/return/return-from-diverging.stderr b/src/test/ui/return/return-from-diverging.stderr
new file mode 100644
index 000000000..0c1fb4d9c
--- /dev/null
+++ b/src/test/ui/return/return-from-diverging.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/return-from-diverging.rs:4:12
+ |
+LL | fn fail() -> ! {
+ | - expected `!` because of return type
+LL | return "wow";
+ | ^^^^^ expected `!`, found `&str`
+ |
+ = note: expected type `!`
+ found reference `&'static str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-impl-trait-bad.rs b/src/test/ui/return/return-impl-trait-bad.rs
new file mode 100644
index 000000000..e3f6ddb9a
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait-bad.rs
@@ -0,0 +1,31 @@
+trait Trait {}
+impl Trait for () {}
+
+fn bad_echo<T>(_t: T) -> T {
+ "this should not suggest impl Trait" //~ ERROR mismatched types
+}
+
+fn bad_echo_2<T: Trait>(_t: T) -> T {
+ "this will not suggest it, because that would probably be wrong" //~ ERROR mismatched types
+}
+
+fn other_bounds_bad<T>() -> T
+where
+ T: Send,
+ Option<T>: Send,
+{
+ "don't suggest this, because Option<T> places additional constraints" //~ ERROR mismatched types
+}
+
+// FIXME: implement this check
+trait GenericTrait<T> {}
+
+fn used_in_trait<T>() -> T
+where
+ T: Send,
+ (): GenericTrait<T>,
+{
+ "don't suggest this, because the generic param is used in the bound." //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/return/return-impl-trait-bad.stderr b/src/test/ui/return/return-impl-trait-bad.stderr
new file mode 100644
index 000000000..237b85ee6
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait-bad.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait-bad.rs:5:5
+ |
+LL | fn bad_echo<T>(_t: T) -> T {
+ | - - expected `T` because of return type
+ | |
+ | this type parameter
+LL | "this should not suggest impl Trait"
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+ |
+ = note: expected type parameter `T`
+ found reference `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait-bad.rs:9:5
+ |
+LL | fn bad_echo_2<T: Trait>(_t: T) -> T {
+ | - - expected `T` because of return type
+ | |
+ | this type parameter
+LL | "this will not suggest it, because that would probably be wrong"
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+ |
+ = note: expected type parameter `T`
+ found reference `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait-bad.rs:17:5
+ |
+LL | fn other_bounds_bad<T>() -> T
+ | - - expected `T` because of return type
+ | |
+ | this type parameter
+...
+LL | "don't suggest this, because Option<T> places additional constraints"
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+ |
+ = note: expected type parameter `T`
+ found reference `&'static str`
+
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait-bad.rs:28:5
+ |
+LL | fn used_in_trait<T>() -> T
+ | - -
+ | | |
+ | | expected `T` because of return type
+ | | help: consider using an impl return type: `impl Send`
+ | this type parameter
+...
+LL | "don't suggest this, because the generic param is used in the bound."
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found `&str`
+ |
+ = note: expected type parameter `T`
+ found reference `&'static str`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-impl-trait.fixed b/src/test/ui/return/return-impl-trait.fixed
new file mode 100644
index 000000000..ff2b02f73
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.fixed
@@ -0,0 +1,30 @@
+// run-rustfix
+
+trait Trait {}
+impl Trait for () {}
+
+// this works
+fn foo() -> impl Trait {
+ ()
+}
+
+fn bar<T: Trait + std::marker::Sync>() -> impl Trait + std::marker::Sync + Send
+where
+ T: Send,
+{
+ () //~ ERROR mismatched types
+}
+
+fn other_bounds<T>() -> impl Trait
+where
+ T: Trait,
+ Vec<usize>: Clone,
+{
+ () //~ ERROR mismatched types
+}
+
+fn main() {
+ foo();
+ bar::<()>();
+ other_bounds::<()>();
+}
diff --git a/src/test/ui/return/return-impl-trait.rs b/src/test/ui/return/return-impl-trait.rs
new file mode 100644
index 000000000..e905d712f
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.rs
@@ -0,0 +1,30 @@
+// run-rustfix
+
+trait Trait {}
+impl Trait for () {}
+
+// this works
+fn foo() -> impl Trait {
+ ()
+}
+
+fn bar<T: Trait + std::marker::Sync>() -> T
+where
+ T: Send,
+{
+ () //~ ERROR mismatched types
+}
+
+fn other_bounds<T>() -> T
+where
+ T: Trait,
+ Vec<usize>: Clone,
+{
+ () //~ ERROR mismatched types
+}
+
+fn main() {
+ foo();
+ bar::<()>();
+ other_bounds::<()>();
+}
diff --git a/src/test/ui/return/return-impl-trait.stderr b/src/test/ui/return/return-impl-trait.stderr
new file mode 100644
index 000000000..43d40972f
--- /dev/null
+++ b/src/test/ui/return/return-impl-trait.stderr
@@ -0,0 +1,34 @@
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait.rs:15:5
+ |
+LL | fn bar<T: Trait + std::marker::Sync>() -> T
+ | - -
+ | | |
+ | | expected `T` because of return type
+ | this type parameter help: consider using an impl return type: `impl Trait + std::marker::Sync + Send`
+...
+LL | ()
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error[E0308]: mismatched types
+ --> $DIR/return-impl-trait.rs:23:5
+ |
+LL | fn other_bounds<T>() -> T
+ | - -
+ | | |
+ | | expected `T` because of return type
+ | | help: consider using an impl return type: `impl Trait`
+ | this type parameter
+...
+LL | ()
+ | ^^ expected type parameter `T`, found `()`
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-match-array-const.rs b/src/test/ui/return/return-match-array-const.rs
new file mode 100644
index 000000000..b619a4d57
--- /dev/null
+++ b/src/test/ui/return/return-match-array-const.rs
@@ -0,0 +1,19 @@
+fn main() {
+//~^ NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
+//~| NOTE: not the enclosing function body
+ [(); return match 0 { n => n }];
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+
+ [(); return match 0 { 0 => 0 }];
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+
+ [(); return match () { 'a' => 0, _ => 0 }];
+ //~^ ERROR: return statement outside of function body [E0572]
+ //~| NOTE: the return is part of this body...
+ //~| ERROR: mismatched types [E0308]
+ //~| NOTE: expected `()`, found `char`
+ //~| NOTE: this expression has type `()`
+}
diff --git a/src/test/ui/return/return-match-array-const.stderr b/src/test/ui/return/return-match-array-const.stderr
new file mode 100644
index 000000000..85a733adf
--- /dev/null
+++ b/src/test/ui/return/return-match-array-const.stderr
@@ -0,0 +1,56 @@
+error[E0572]: return statement outside of function body
+ --> $DIR/return-match-array-const.rs:5:10
+ |
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+LL | | [(); return match 0 { n => n }];
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+... |
+LL | |
+LL | | }
+ | |_- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+ --> $DIR/return-match-array-const.rs:9:10
+ |
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+... |
+LL | | [(); return match 0 { 0 => 0 }];
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+... |
+LL | |
+LL | | }
+ | |_- ...not the enclosing function body
+
+error[E0572]: return statement outside of function body
+ --> $DIR/return-match-array-const.rs:13:10
+ |
+LL | / fn main() {
+LL | |
+LL | |
+LL | |
+... |
+LL | | [(); return match () { 'a' => 0, _ => 0 }];
+ | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body...
+... |
+LL | |
+LL | | }
+ | |_- ...not the enclosing function body
+
+error[E0308]: mismatched types
+ --> $DIR/return-match-array-const.rs:13:28
+ |
+LL | [(); return match () { 'a' => 0, _ => 0 }];
+ | -- ^^^ expected `()`, found `char`
+ | |
+ | this expression has type `()`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0572.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-type.rs b/src/test/ui/return/return-type.rs
new file mode 100644
index 000000000..9f951ee0d
--- /dev/null
+++ b/src/test/ui/return/return-type.rs
@@ -0,0 +1,14 @@
+struct S<T> {
+ t: T,
+}
+
+fn foo<T>(x: T) -> S<T> {
+ S { t: x }
+}
+
+fn bar() {
+ foo(4 as usize)
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/return/return-type.stderr b/src/test/ui/return/return-type.stderr
new file mode 100644
index 000000000..5af136e60
--- /dev/null
+++ b/src/test/ui/return/return-type.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/return-type.rs:10:5
+ |
+LL | foo(4 as usize)
+ | ^^^^^^^^^^^^^^^ expected `()`, found struct `S`
+ |
+ = note: expected unit type `()`
+ found struct `S<usize>`
+help: consider using a semicolon here
+ |
+LL | foo(4 as usize);
+ | +
+help: try adding a return type
+ |
+LL | fn bar() -> S<usize> {
+ | +++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/return/return-unit-from-diverging.rs b/src/test/ui/return/return-unit-from-diverging.rs
new file mode 100644
index 000000000..48417599b
--- /dev/null
+++ b/src/test/ui/return/return-unit-from-diverging.rs
@@ -0,0 +1,9 @@
+// Test that we get the usual error that we'd get for any other return type and not something about
+// diverging functions not being able to return.
+
+fn fail() -> ! {
+ return; //~ ERROR in a function whose return type is not
+}
+
+fn main() {
+}
diff --git a/src/test/ui/return/return-unit-from-diverging.stderr b/src/test/ui/return/return-unit-from-diverging.stderr
new file mode 100644
index 000000000..befc57563
--- /dev/null
+++ b/src/test/ui/return/return-unit-from-diverging.stderr
@@ -0,0 +1,11 @@
+error[E0069]: `return;` in a function whose return type is not `()`
+ --> $DIR/return-unit-from-diverging.rs:5:5
+ |
+LL | fn fail() -> ! {
+ | - expected `!` because of this return type
+LL | return;
+ | ^^^^^^ return type is not `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0069`.
diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs
new file mode 100644
index 000000000..2c3610fb2
--- /dev/null
+++ b/src/test/ui/return/tail-expr-as-potential-return.rs
@@ -0,0 +1,32 @@
+// > Suggest `return`ing tail expressions that match return type
+// >
+// > Some newcomers are confused by the behavior of tail expressions,
+// > interpreting that "leaving out the `;` makes it the return value".
+// > To help them go in the right direction, suggest using `return` instead
+// > when applicable.
+// (original commit description for this test)
+//
+// This test was amended to also serve as a regression test for #92308, where
+// this suggestion would not trigger with async functions.
+//
+// edition:2018
+
+fn main() {
+ let _ = foo(true);
+}
+
+fn foo(x: bool) -> Result<f64, i32> {
+ if x {
+ Err(42) //~ ERROR mismatched types
+ //| HELP you might have meant to return this value
+ }
+ Ok(42.0)
+}
+
+async fn bar(x: bool) -> Result<f64, i32> {
+ if x {
+ Err(42) //~ ERROR mismatched types
+ //| HELP you might have meant to return this value
+ }
+ Ok(42.0)
+}
diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr
new file mode 100644
index 000000000..dec1cbc46
--- /dev/null
+++ b/src/test/ui/return/tail-expr-as-potential-return.stderr
@@ -0,0 +1,37 @@
+error[E0308]: mismatched types
+ --> $DIR/tail-expr-as-potential-return.rs:28:9
+ |
+LL | / if x {
+LL | | Err(42)
+ | | ^^^^^^^ expected `()`, found enum `Result`
+LL | | //| HELP you might have meant to return this value
+LL | | }
+ | |_____- expected this to be `()`
+ |
+ = note: expected unit type `()`
+ found enum `Result<_, {integer}>`
+help: you might have meant to return this value
+ |
+LL | return Err(42);
+ | ++++++ +
+
+error[E0308]: mismatched types
+ --> $DIR/tail-expr-as-potential-return.rs:20:9
+ |
+LL | / if x {
+LL | | Err(42)
+ | | ^^^^^^^ expected `()`, found enum `Result`
+LL | | //| HELP you might have meant to return this value
+LL | | }
+ | |_____- expected this to be `()`
+ |
+ = note: expected unit type `()`
+ found enum `Result<_, {integer}>`
+help: you might have meant to return this value
+ |
+LL | return Err(42);
+ | ++++++ +
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.