diff options
Diffstat (limited to 'tests/ui/return')
21 files changed, 593 insertions, 0 deletions
diff --git a/tests/ui/return/issue-64620.rs b/tests/ui/return/issue-64620.rs new file mode 100644 index 000000000..a62e5bf8d --- /dev/null +++ b/tests/ui/return/issue-64620.rs @@ -0,0 +1,5 @@ +enum Bug { + V1 = return [0][0] //~ERROR return statement outside of function body +} + +fn main() {} diff --git a/tests/ui/return/issue-64620.stderr b/tests/ui/return/issue-64620.stderr new file mode 100644 index 000000000..f40ac4de3 --- /dev/null +++ b/tests/ui/return/issue-64620.stderr @@ -0,0 +1,9 @@ +error[E0572]: return statement outside of function body + --> $DIR/issue-64620.rs:2:10 + | +LL | V1 = return [0][0] + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0572`. diff --git a/tests/ui/return/issue-82612-return-mutable-reference.rs b/tests/ui/return/issue-82612-return-mutable-reference.rs new file mode 100644 index 000000000..db0d08ddb --- /dev/null +++ b/tests/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/tests/ui/return/issue-82612-return-mutable-reference.stderr b/tests/ui/return/issue-82612-return-mutable-reference.stderr new file mode 100644 index 000000000..eb2322d51 --- /dev/null +++ b/tests/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/tests/ui/return/issue-86188-return-not-in-fn-body.rs b/tests/ui/return/issue-86188-return-not-in-fn-body.rs new file mode 100644 index 000000000..4f076fa06 --- /dev/null +++ b/tests/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/tests/ui/return/issue-86188-return-not-in-fn-body.stderr b/tests/ui/return/issue-86188-return-not-in-fn-body.stderr new file mode 100644 index 000000000..4f938670e --- /dev/null +++ b/tests/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/tests/ui/return/return-from-diverging.rs b/tests/ui/return/return-from-diverging.rs new file mode 100644 index 000000000..2ee48e7bc --- /dev/null +++ b/tests/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/tests/ui/return/return-from-diverging.stderr b/tests/ui/return/return-from-diverging.stderr new file mode 100644 index 000000000..0c1fb4d9c --- /dev/null +++ b/tests/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/tests/ui/return/return-impl-trait-bad.rs b/tests/ui/return/return-impl-trait-bad.rs new file mode 100644 index 000000000..e3f6ddb9a --- /dev/null +++ b/tests/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/tests/ui/return/return-impl-trait-bad.stderr b/tests/ui/return/return-impl-trait-bad.stderr new file mode 100644 index 000000000..237b85ee6 --- /dev/null +++ b/tests/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/tests/ui/return/return-impl-trait.fixed b/tests/ui/return/return-impl-trait.fixed new file mode 100644 index 000000000..ff2b02f73 --- /dev/null +++ b/tests/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/tests/ui/return/return-impl-trait.rs b/tests/ui/return/return-impl-trait.rs new file mode 100644 index 000000000..e905d712f --- /dev/null +++ b/tests/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/tests/ui/return/return-impl-trait.stderr b/tests/ui/return/return-impl-trait.stderr new file mode 100644 index 000000000..43d40972f --- /dev/null +++ b/tests/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/tests/ui/return/return-match-array-const.rs b/tests/ui/return/return-match-array-const.rs new file mode 100644 index 000000000..b619a4d57 --- /dev/null +++ b/tests/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/tests/ui/return/return-match-array-const.stderr b/tests/ui/return/return-match-array-const.stderr new file mode 100644 index 000000000..85a733adf --- /dev/null +++ b/tests/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/tests/ui/return/return-type.rs b/tests/ui/return/return-type.rs new file mode 100644 index 000000000..9f951ee0d --- /dev/null +++ b/tests/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/tests/ui/return/return-type.stderr b/tests/ui/return/return-type.stderr new file mode 100644 index 000000000..5af136e60 --- /dev/null +++ b/tests/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/tests/ui/return/return-unit-from-diverging.rs b/tests/ui/return/return-unit-from-diverging.rs new file mode 100644 index 000000000..48417599b --- /dev/null +++ b/tests/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/tests/ui/return/return-unit-from-diverging.stderr b/tests/ui/return/return-unit-from-diverging.stderr new file mode 100644 index 000000000..befc57563 --- /dev/null +++ b/tests/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/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs new file mode 100644 index 000000000..f46e088b8 --- /dev/null +++ b/tests/ui/return/tail-expr-as-potential-return.rs @@ -0,0 +1,47 @@ +// > 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() { +} + +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) +} + +trait Identity { + type Out; +} + +impl<T> Identity for T { + type Out = T; +} + +async fn foo2() -> i32 { + if true { + 1i32 //~ ERROR mismatched types + //| HELP you might have meant to return this value + } + 0 +} diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr new file mode 100644 index 000000000..9183b4599 --- /dev/null +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -0,0 +1,52 @@ +error[E0308]: mismatched types + --> $DIR/tail-expr-as-potential-return.rs:27: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:43:9 + | +LL | / if true { +LL | | 1i32 + | | ^^^^ expected `()`, found `i32` +LL | | //| HELP you might have meant to return this value +LL | | } + | |_____- expected this to be `()` + | +help: you might have meant to return this value + | +LL | return 1i32; + | ++++++ + + +error[E0308]: mismatched types + --> $DIR/tail-expr-as-potential-return.rs:19: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 3 previous errors + +For more information about this error, try `rustc --explain E0308`. |