diff options
Diffstat (limited to '')
61 files changed, 1281 insertions, 0 deletions
diff --git a/src/test/ui/reachable-unnameable-type-alias.rs b/src/test/ui/reachable-unnameable-type-alias.rs new file mode 100644 index 000000000..461355f87 --- /dev/null +++ b/src/test/ui/reachable-unnameable-type-alias.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(staged_api)] +#![stable(feature = "a", since = "b")] + +mod inner_private_module { + // UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here + pub type UnnameableTypeAlias = u8; +} + +#[stable(feature = "a", since = "b")] +pub fn f() -> inner_private_module::UnnameableTypeAlias { + 0 +} + +fn main() {} diff --git a/src/test/ui/reachable/README.md b/src/test/ui/reachable/README.md new file mode 100644 index 000000000..8bed5fba7 --- /dev/null +++ b/src/test/ui/reachable/README.md @@ -0,0 +1,7 @@ +A variety of tests around reachability. These tests in general check +two things: + +- that we get unreachable code warnings in reasonable locations; +- that we permit coercions **into** `!` from expressions which + diverge, where an expression "diverges" if it must execute some + subexpression of type `!`, or it has type `!` itself. diff --git a/src/test/ui/reachable/auxiliary/unreachable_variant.rs b/src/test/ui/reachable/auxiliary/unreachable_variant.rs new file mode 100644 index 000000000..4e94a4b5e --- /dev/null +++ b/src/test/ui/reachable/auxiliary/unreachable_variant.rs @@ -0,0 +1,5 @@ +mod super_sekrit { + pub enum sooper_sekrit { + quux, baz + } +} diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs new file mode 100644 index 000000000..b45e5daf4 --- /dev/null +++ b/src/test/ui/reachable/expr_add.rs @@ -0,0 +1,18 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![deny(unreachable_code)] + +use std::ops; + +struct Foo; + +impl ops::Add<!> for Foo { + type Output = !; + fn add(self, rhs: !) -> ! { + unimplemented!() + } +} + +fn main() { + let x = Foo + return; //~ ERROR unreachable +} diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr new file mode 100644 index 000000000..692bd20f5 --- /dev/null +++ b/src/test/ui/reachable/expr_add.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_add.rs:17:13 + | +LL | let x = Foo + return; + | ^^^^^^------ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_add.rs:3:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_again.rs b/src/test/ui/reachable/expr_again.rs new file mode 100644 index 000000000..604932133 --- /dev/null +++ b/src/test/ui/reachable/expr_again.rs @@ -0,0 +1,11 @@ +#![allow(unused_variables)] + +#![deny(unreachable_code)] + +fn main() { + let x = loop { + continue; + println!("hi"); + //~^ ERROR unreachable statement + }; +} diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr new file mode 100644 index 000000000..a3c54e135 --- /dev/null +++ b/src/test/ui/reachable/expr_again.stderr @@ -0,0 +1,17 @@ +error: unreachable statement + --> $DIR/expr_again.rs:8:9 + | +LL | continue; + | -------- any code following this expression is unreachable +LL | println!("hi"); + | ^^^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/expr_again.rs:3:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_andand.rs b/src/test/ui/reachable/expr_andand.rs new file mode 100644 index 000000000..d37eb0a3b --- /dev/null +++ b/src/test/ui/reachable/expr_andand.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + // No error here. + let x = false && (return); + println!("I am not dead."); +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs new file mode 100644 index 000000000..e6bdb9705 --- /dev/null +++ b/src/test/ui/reachable/expr_array.rs @@ -0,0 +1,17 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the `22` is unreachable: + let x: [usize; 2] = [return, 22]; //~ ERROR unreachable +} + +fn b() { + // the array is unreachable: + let x: [usize; 2] = [22, return]; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr new file mode 100644 index 000000000..e144d7184 --- /dev/null +++ b/src/test/ui/reachable/expr_array.stderr @@ -0,0 +1,25 @@ +error: unreachable expression + --> $DIR/expr_array.rs:9:34 + | +LL | let x: [usize; 2] = [return, 22]; + | ------ ^^ unreachable expression + | | + | any code following this expression is unreachable + | +note: the lint level is defined here + --> $DIR/expr_array.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_array.rs:14:25 + | +LL | let x: [usize; 2] = [22, return]; + | ^^^^^------^ + | | | + | | any code following this expression is unreachable + | unreachable expression + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs new file mode 100644 index 000000000..e547f75e2 --- /dev/null +++ b/src/test/ui/reachable/expr_assign.rs @@ -0,0 +1,29 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + // No error here. + let x; + x = return; //~ ERROR unreachable +} + +fn bar() { + use std::ptr; + let p: *mut ! = ptr::null_mut::<!>(); + unsafe { + // Here we consider the `return` unreachable because + // "evaluating" the `*p` has type `!`. This is somewhat + // dubious, I suppose. + *p = return; //~ ERROR unreachable + } +} + +fn baz() { + let mut i = 0; + *{return; &mut i} = 22; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr new file mode 100644 index 000000000..c51156b3f --- /dev/null +++ b/src/test/ui/reachable/expr_assign.stderr @@ -0,0 +1,33 @@ +error: unreachable expression + --> $DIR/expr_assign.rs:10:5 + | +LL | x = return; + | ^^^^------ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_assign.rs:5:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_assign.rs:20:14 + | +LL | *p = return; + | -- ^^^^^^ unreachable expression + | | + | any code following this expression is unreachable + +error: unreachable expression + --> $DIR/expr_assign.rs:26:15 + | +LL | *{return; &mut i} = 22; + | ------ ^^^^^^ unreachable expression + | | + | any code following this expression is unreachable + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs new file mode 100644 index 000000000..136bccce8 --- /dev/null +++ b/src/test/ui/reachable/expr_block.rs @@ -0,0 +1,31 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn a() { + // Here the tail expression is considered unreachable: + let x = { + return; + 22 //~ ERROR unreachable + }; +} + +fn b() { + // Here the `x` assignment is considered unreachable, not the block: + let x = { + return; + }; +} + +fn c() { + // Here the `println!` is unreachable: + let x = { + return; + println!("foo"); + //~^ ERROR unreachable statement + 22 + }; +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr new file mode 100644 index 000000000..d5f248a24 --- /dev/null +++ b/src/test/ui/reachable/expr_block.stderr @@ -0,0 +1,26 @@ +error: unreachable expression + --> $DIR/expr_block.rs:10:9 + | +LL | return; + | ------ any code following this expression is unreachable +LL | 22 + | ^^ unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_block.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable statement + --> $DIR/expr_block.rs:25:9 + | +LL | return; + | ------ any code following this expression is unreachable +LL | println!("foo"); + | ^^^^^^^^^^^^^^^ unreachable statement + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_box.rs b/src/test/ui/reachable/expr_box.rs new file mode 100644 index 000000000..00328ea01 --- /dev/null +++ b/src/test/ui/reachable/expr_box.rs @@ -0,0 +1,8 @@ +#![feature(box_syntax)] +#![allow(unused_variables)] +#![deny(unreachable_code)] + +fn main() { + let x = box return; //~ ERROR unreachable + println!("hi"); +} diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr new file mode 100644 index 000000000..ea6472cbe --- /dev/null +++ b/src/test/ui/reachable/expr_box.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_box.rs:6:13 + | +LL | let x = box return; + | ^^^^------ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_box.rs:3:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs new file mode 100644 index 000000000..1eaa96c3c --- /dev/null +++ b/src/test/ui/reachable/expr_call.rs @@ -0,0 +1,21 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo(x: !, y: usize) { } + +fn bar(x: !) { } + +fn a() { + // the `22` is unreachable: + foo(return, 22); //~ ERROR unreachable +} + +fn b() { + // the call is unreachable: + bar(return); //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr new file mode 100644 index 000000000..a5ad9a329 --- /dev/null +++ b/src/test/ui/reachable/expr_call.stderr @@ -0,0 +1,24 @@ +error: unreachable expression + --> $DIR/expr_call.rs:13:17 + | +LL | foo(return, 22); + | ------ ^^ unreachable expression + | | + | any code following this expression is unreachable + | +note: the lint level is defined here + --> $DIR/expr_call.rs:5:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable call + --> $DIR/expr_call.rs:18:5 + | +LL | bar(return); + | ^^^ ------ any code following this expression is unreachable + | | + | unreachable call + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs new file mode 100644 index 000000000..e8e477ea4 --- /dev/null +++ b/src/test/ui/reachable/expr_cast.rs @@ -0,0 +1,13 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(never_type, type_ascription)] + +fn a() { + // the cast is unreachable: + let x = {return} as !; //~ ERROR unreachable + //~| ERROR non-primitive cast +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr new file mode 100644 index 000000000..6643f1784 --- /dev/null +++ b/src/test/ui/reachable/expr_cast.stderr @@ -0,0 +1,24 @@ +error: unreachable expression + --> $DIR/expr_cast.rs:9:13 + | +LL | let x = {return} as !; + | ^------^^^^^^ + | || + | |any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_cast.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error[E0605]: non-primitive cast: `()` as `!` + --> $DIR/expr_cast.rs:9:13 + | +LL | let x = {return} as !; + | ^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0605`. diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs new file mode 100644 index 000000000..3c04eaf48 --- /dev/null +++ b/src/test/ui/reachable/expr_if.rs @@ -0,0 +1,31 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + if {return} { //~ ERROR unreachable block in `if` + println!("Hello, world!"); + } +} + +fn bar() { + if {true} { + return; + } + println!("I am not dead."); +} + +fn baz() { + if {true} { + return; + } else { + return; + } + // As the next action to be taken after the if arms, we should + // report the `println!` as unreachable: + println!("But I am."); + //~^ ERROR unreachable statement +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr new file mode 100644 index 000000000..ebd0b5a3e --- /dev/null +++ b/src/test/ui/reachable/expr_if.stderr @@ -0,0 +1,30 @@ +error: unreachable block in `if` or `while` expression + --> $DIR/expr_if.rs:7:17 + | +LL | if {return} { + | _________------__^ + | | | + | | any code following this expression is unreachable +LL | | println!("Hello, world!"); +LL | | } + | |_____^ unreachable block in `if` or `while` expression + | +note: the lint level is defined here + --> $DIR/expr_if.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable statement + --> $DIR/expr_if.rs:27:5 + | +LL | return; + | ------ any code following this expression is unreachable +... +LL | println!("But I am."); + | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs new file mode 100644 index 000000000..7eab6f7bb --- /dev/null +++ b/src/test/ui/reachable/expr_loop.rs @@ -0,0 +1,36 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn a() { + loop { return; } + println!("I am dead."); + //~^ ERROR unreachable statement +} + +fn b() { + loop { + break; + } + println!("I am not dead."); +} + +fn c() { + loop { return; } + println!("I am dead."); + //~^ ERROR unreachable statement +} + +fn d() { + 'outer: loop { loop { break 'outer; } } + println!("I am not dead."); +} + +fn e() { + loop { 'middle: loop { loop { break 'middle; } } } + println!("I am dead."); + //~^ ERROR unreachable statement +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr new file mode 100644 index 000000000..918584686 --- /dev/null +++ b/src/test/ui/reachable/expr_loop.stderr @@ -0,0 +1,37 @@ +error: unreachable statement + --> $DIR/expr_loop.rs:8:5 + | +LL | loop { return; } + | ------ any code following this expression is unreachable +LL | println!("I am dead."); + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/expr_loop.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unreachable statement + --> $DIR/expr_loop.rs:21:5 + | +LL | loop { return; } + | ------ any code following this expression is unreachable +LL | println!("I am dead."); + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unreachable statement + --> $DIR/expr_loop.rs:32:5 + | +LL | loop { 'middle: loop { loop { break 'middle; } } } + | -------------------------------------------------- any code following this expression is unreachable +LL | println!("I am dead."); + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs new file mode 100644 index 000000000..2fd26b54e --- /dev/null +++ b/src/test/ui/reachable/expr_match.rs @@ -0,0 +1,39 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn b() { + match () { () => return } + println!("I am dead"); + //~^ ERROR unreachable statement +} + +fn c() { + match () { () if false => return, () => () } + println!("I am not dead"); +} + +fn d() { + match () { () if false => return, () => return } + println!("I am dead"); + //~^ ERROR unreachable statement +} + +fn e() { + // Here the compiler fails to figure out that the `println` is dead. + match () { () if return => (), () => return } + println!("I am dead"); +} + +fn f() { + match Some(()) { None => (), Some(()) => return } + println!("I am not dead"); +} + +fn g() { + match Some(()) { None => return, Some(()) => () } + println!("I am not dead"); +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr new file mode 100644 index 000000000..d15208609 --- /dev/null +++ b/src/test/ui/reachable/expr_match.stderr @@ -0,0 +1,27 @@ +error: unreachable statement + --> $DIR/expr_match.rs:8:5 + | +LL | match () { () => return } + | ------------------------- any code following this `match` expression is unreachable, as all arms diverge +LL | println!("I am dead"); + | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/expr_match.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unreachable statement + --> $DIR/expr_match.rs:19:5 + | +LL | match () { () if false => return, () => return } + | ------------------------------------------------ any code following this `match` expression is unreachable, as all arms diverge +LL | println!("I am dead"); + | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs new file mode 100644 index 000000000..d917df05b --- /dev/null +++ b/src/test/ui/reachable/expr_method.rs @@ -0,0 +1,24 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +struct Foo; + +impl Foo { + fn foo(&self, x: !, y: usize) { } + fn bar(&self, x: !) { } +} + +fn a() { + // the `22` is unreachable: + Foo.foo(return, 22); //~ ERROR unreachable +} + +fn b() { + // the call is unreachable: + Foo.bar(return); //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr new file mode 100644 index 000000000..41c3b8a39 --- /dev/null +++ b/src/test/ui/reachable/expr_method.stderr @@ -0,0 +1,24 @@ +error: unreachable expression + --> $DIR/expr_method.rs:16:21 + | +LL | Foo.foo(return, 22); + | ------ ^^ unreachable expression + | | + | any code following this expression is unreachable + | +note: the lint level is defined here + --> $DIR/expr_method.rs:5:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable call + --> $DIR/expr_method.rs:21:9 + | +LL | Foo.bar(return); + | ^^^ ------ any code following this expression is unreachable + | | + | unreachable call + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_oror.rs b/src/test/ui/reachable/expr_oror.rs new file mode 100644 index 000000000..e95062de4 --- /dev/null +++ b/src/test/ui/reachable/expr_oror.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + let x = false || (return); + println!("I am not dead."); +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs new file mode 100644 index 000000000..0fd13c6cb --- /dev/null +++ b/src/test/ui/reachable/expr_repeat.rs @@ -0,0 +1,12 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the repeat is unreachable: + let x: [usize; 2] = [return; 2]; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr new file mode 100644 index 000000000..defa87046 --- /dev/null +++ b/src/test/ui/reachable/expr_repeat.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_repeat.rs:9:25 + | +LL | let x: [usize; 2] = [return; 2]; + | ^------^^^^ + | || + | |any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_repeat.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_return.rs b/src/test/ui/reachable/expr_return.rs new file mode 100644 index 000000000..0fc43f450 --- /dev/null +++ b/src/test/ui/reachable/expr_return.rs @@ -0,0 +1,13 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // Here we issue that the "2nd-innermost" return is unreachable, + // but we stop there. + let x = {return {return {return;}}}; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr new file mode 100644 index 000000000..e1bef80ae --- /dev/null +++ b/src/test/ui/reachable/expr_return.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_return.rs:10:22 + | +LL | let x = {return {return {return;}}}; + | ^^^^^^^^------^^ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_return.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_return_in_macro.rs b/src/test/ui/reachable/expr_return_in_macro.rs new file mode 100644 index 000000000..4e57618bf --- /dev/null +++ b/src/test/ui/reachable/expr_return_in_macro.rs @@ -0,0 +1,15 @@ +// Tests that we generate nice error messages +// when an expression is unreachble due to control +// flow inside of a macro expansion. +#![deny(unreachable_code)] + +macro_rules! early_return { + () => { + return () + } +} + +fn main() { + return early_return!(); + //~^ ERROR unreachable expression +} diff --git a/src/test/ui/reachable/expr_return_in_macro.stderr b/src/test/ui/reachable/expr_return_in_macro.stderr new file mode 100644 index 000000000..3c562a7ee --- /dev/null +++ b/src/test/ui/reachable/expr_return_in_macro.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_return_in_macro.rs:13:5 + | +LL | return () + | --------- any code following this expression is unreachable +... +LL | return early_return!(); + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_return_in_macro.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_struct.rs b/src/test/ui/reachable/expr_struct.rs new file mode 100644 index 000000000..31ab40582 --- /dev/null +++ b/src/test/ui/reachable/expr_struct.rs @@ -0,0 +1,32 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +struct Foo { + a: usize, + b: usize, +} + +fn a() { + // struct expr is unreachable: + let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable +} + +fn b() { + // the `33` is unreachable: + let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable +} + +fn c() { + // the `..return` is unreachable: + let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable +} + +fn d() { + // the struct expr is unreachable: + let x = Foo { a: 22, b: return }; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr new file mode 100644 index 000000000..36b070456 --- /dev/null +++ b/src/test/ui/reachable/expr_struct.stderr @@ -0,0 +1,42 @@ +error: unreachable expression + --> $DIR/expr_struct.rs:14:13 + | +LL | let x = Foo { a: 22, b: 33, ..return }; + | ^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_struct.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_struct.rs:19:33 + | +LL | let x = Foo { a: return, b: 33, ..return }; + | ------ ^^ unreachable expression + | | + | any code following this expression is unreachable + +error: unreachable expression + --> $DIR/expr_struct.rs:24:39 + | +LL | let x = Foo { a: 22, b: return, ..return }; + | ------ ^^^^^^ unreachable expression + | | + | any code following this expression is unreachable + +error: unreachable expression + --> $DIR/expr_struct.rs:29:13 + | +LL | let x = Foo { a: 22, b: return }; + | ^^^^^^^^^^^^^^^^------^^ + | | | + | | any code following this expression is unreachable + | unreachable expression + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/reachable/expr_tup.rs b/src/test/ui/reachable/expr_tup.rs new file mode 100644 index 000000000..90d4382e2 --- /dev/null +++ b/src/test/ui/reachable/expr_tup.rs @@ -0,0 +1,17 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the `2` is unreachable: + let x: (usize, usize) = (return, 2); //~ ERROR unreachable +} + +fn b() { + // the tuple is unreachable: + let x: (usize, usize) = (2, return); //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr new file mode 100644 index 000000000..5ea6bf4ab --- /dev/null +++ b/src/test/ui/reachable/expr_tup.stderr @@ -0,0 +1,25 @@ +error: unreachable expression + --> $DIR/expr_tup.rs:9:38 + | +LL | let x: (usize, usize) = (return, 2); + | ------ ^ unreachable expression + | | + | any code following this expression is unreachable + | +note: the lint level is defined here + --> $DIR/expr_tup.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_tup.rs:14:29 + | +LL | let x: (usize, usize) = (2, return); + | ^^^^------^ + | | | + | | any code following this expression is unreachable + | unreachable expression + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs new file mode 100644 index 000000000..8d32397b5 --- /dev/null +++ b/src/test/ui/reachable/expr_type.rs @@ -0,0 +1,12 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(never_type, type_ascription)] + +fn a() { + // the cast is unreachable: + let x = {return}: !; //~ ERROR unreachable +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr new file mode 100644 index 000000000..c56c64be7 --- /dev/null +++ b/src/test/ui/reachable/expr_type.stderr @@ -0,0 +1,17 @@ +error: unreachable expression + --> $DIR/expr_type.rs:9:13 + | +LL | let x = {return}: !; + | ^------^^^^ + | || + | |any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_type.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs new file mode 100644 index 000000000..190c7447d --- /dev/null +++ b/src/test/ui/reachable/expr_unary.rs @@ -0,0 +1,12 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + let x: ! = * { return; }; //~ ERROR unreachable + //~| ERROR type `!` cannot be dereferenced +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr new file mode 100644 index 000000000..0a763087c --- /dev/null +++ b/src/test/ui/reachable/expr_unary.stderr @@ -0,0 +1,24 @@ +error[E0614]: type `!` cannot be dereferenced + --> $DIR/expr_unary.rs:8:16 + | +LL | let x: ! = * { return; }; + | ^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_unary.rs:8:16 + | +LL | let x: ! = * { return; }; + | ^^^^------^^^ + | | | + | | any code following this expression is unreachable + | unreachable expression + | +note: the lint level is defined here + --> $DIR/expr_unary.rs:5:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0614`. diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs new file mode 100644 index 000000000..5005f3833 --- /dev/null +++ b/src/test/ui/reachable/expr_while.rs @@ -0,0 +1,29 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + while {return} { + //~^ ERROR unreachable block in `if` + println!("Hello, world!"); + } +} + +fn bar() { + while {true} { + return; + } + println!("I am not dead."); +} + +fn baz() { + // Here, we cite the `while` loop as dead. + while {return} { + //~^ ERROR unreachable block in `if` + println!("I am dead."); + } + println!("I am, too."); +} + +fn main() { } diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr new file mode 100644 index 000000000..b1859f619 --- /dev/null +++ b/src/test/ui/reachable/expr_while.stderr @@ -0,0 +1,32 @@ +error: unreachable block in `if` or `while` expression + --> $DIR/expr_while.rs:7:20 + | +LL | while {return} { + | ____________------__^ + | | | + | | any code following this expression is unreachable +LL | | +LL | | println!("Hello, world!"); +LL | | } + | |_____^ unreachable block in `if` or `while` expression + | +note: the lint level is defined here + --> $DIR/expr_while.rs:4:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable block in `if` or `while` expression + --> $DIR/expr_while.rs:22:20 + | +LL | while {return} { + | ____________------__^ + | | | + | | any code following this expression is unreachable +LL | | +LL | | println!("I am dead."); +LL | | } + | |_____^ unreachable block in `if` or `while` expression + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/unreachable-arm.rs b/src/test/ui/reachable/unreachable-arm.rs new file mode 100644 index 000000000..3277bf0d5 --- /dev/null +++ b/src/test/ui/reachable/unreachable-arm.rs @@ -0,0 +1,14 @@ +#![feature(box_patterns)] + +#![allow(dead_code)] +#![deny(unreachable_patterns)] + +enum Foo { A(Box<Foo>, isize), B(usize), } + +fn main() { + match Foo::B(1) { + Foo::B(_) | Foo::A(box _, 1) => { } + Foo::A(_, 1) => { } //~ ERROR unreachable pattern + _ => { } + } +} diff --git a/src/test/ui/reachable/unreachable-arm.stderr b/src/test/ui/reachable/unreachable-arm.stderr new file mode 100644 index 000000000..1cbea8288 --- /dev/null +++ b/src/test/ui/reachable/unreachable-arm.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/unreachable-arm.rs:11:9 + | +LL | Foo::A(_, 1) => { } + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unreachable-arm.rs:4:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/unreachable-code-ret.rs b/src/test/ui/reachable/unreachable-code-ret.rs new file mode 100644 index 000000000..fad35794f --- /dev/null +++ b/src/test/ui/reachable/unreachable-code-ret.rs @@ -0,0 +1,8 @@ +// error-pattern: unreachable statement + +#![deny(unreachable_code)] + +fn main() { + return; + println!("Paul is dead"); +} diff --git a/src/test/ui/reachable/unreachable-code-ret.stderr b/src/test/ui/reachable/unreachable-code-ret.stderr new file mode 100644 index 000000000..263a1b5a9 --- /dev/null +++ b/src/test/ui/reachable/unreachable-code-ret.stderr @@ -0,0 +1,17 @@ +error: unreachable statement + --> $DIR/unreachable-code-ret.rs:7:5 + | +LL | return; + | ------ any code following this expression is unreachable +LL | println!("Paul is dead"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/unreachable-code-ret.rs:3:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/unreachable-code.rs b/src/test/ui/reachable/unreachable-code.rs new file mode 100644 index 000000000..ad0dc8a8b --- /dev/null +++ b/src/test/ui/reachable/unreachable-code.rs @@ -0,0 +1,8 @@ +#![deny(unreachable_code)] +#![allow(unused_variables)] + +fn main() { + loop{} + + let a = 3; //~ ERROR: unreachable statement +} diff --git a/src/test/ui/reachable/unreachable-code.stderr b/src/test/ui/reachable/unreachable-code.stderr new file mode 100644 index 000000000..cb1b760c2 --- /dev/null +++ b/src/test/ui/reachable/unreachable-code.stderr @@ -0,0 +1,17 @@ +error: unreachable statement + --> $DIR/unreachable-code.rs:7:3 + | +LL | loop{} + | ------ any code following this expression is unreachable +LL | +LL | let a = 3; + | ^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/unreachable-code.rs:1:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/unreachable-in-call.rs b/src/test/ui/reachable/unreachable-in-call.rs new file mode 100644 index 000000000..dd94e79f4 --- /dev/null +++ b/src/test/ui/reachable/unreachable-in-call.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn diverge() -> ! { panic!() } + +fn get_u8() -> u8 { + 1 +} +fn call(_: u8, _: u8) { + +} +fn diverge_first() { + call(diverge(), + get_u8()); //~ ERROR unreachable expression +} +fn diverge_second() { + call( //~ ERROR unreachable call + get_u8(), + diverge()); +} + +fn main() {} diff --git a/src/test/ui/reachable/unreachable-in-call.stderr b/src/test/ui/reachable/unreachable-in-call.stderr new file mode 100644 index 000000000..cdfa79bf8 --- /dev/null +++ b/src/test/ui/reachable/unreachable-in-call.stderr @@ -0,0 +1,25 @@ +error: unreachable expression + --> $DIR/unreachable-in-call.rs:14:10 + | +LL | call(diverge(), + | --------- any code following this expression is unreachable +LL | get_u8()); + | ^^^^^^^^ unreachable expression + | +note: the lint level is defined here + --> $DIR/unreachable-in-call.rs:2:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable call + --> $DIR/unreachable-in-call.rs:17:5 + | +LL | call( + | ^^^^ unreachable call +LL | get_u8(), +LL | diverge()); + | --------- any code following this expression is unreachable + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/reachable/unreachable-loop-patterns.rs b/src/test/ui/reachable/unreachable-loop-patterns.rs new file mode 100644 index 000000000..e9cef5f47 --- /dev/null +++ b/src/test/ui/reachable/unreachable-loop-patterns.rs @@ -0,0 +1,20 @@ +#![feature(never_type, never_type_fallback)] +#![feature(exhaustive_patterns)] + +#![allow(unreachable_code)] +#![deny(unreachable_patterns)] + +enum Void {} + +impl Iterator for Void { + type Item = Void; + + fn next(&mut self) -> Option<Void> { + None + } +} + +fn main() { + for _ in unimplemented!() as Void {} + //~^ ERROR unreachable pattern +} diff --git a/src/test/ui/reachable/unreachable-loop-patterns.stderr b/src/test/ui/reachable/unreachable-loop-patterns.stderr new file mode 100644 index 000000000..80ffa5d73 --- /dev/null +++ b/src/test/ui/reachable/unreachable-loop-patterns.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/unreachable-loop-patterns.rs:18:9 + | +LL | for _ in unimplemented!() as Void {} + | ^ + | +note: the lint level is defined here + --> $DIR/unreachable-loop-patterns.rs:5:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/reachable/unreachable-try-pattern.rs b/src/test/ui/reachable/unreachable-try-pattern.rs new file mode 100644 index 000000000..23360e73f --- /dev/null +++ b/src/test/ui/reachable/unreachable-try-pattern.rs @@ -0,0 +1,41 @@ +// check-pass +#![feature(never_type, exhaustive_patterns)] +#![warn(unreachable_code)] +#![warn(unreachable_patterns)] + +enum Void {} + +impl From<Void> for i32 { + fn from(v: Void) -> i32 { + match v {} + } +} + +fn bar(x: Result<!, i32>) -> Result<u32, i32> { + x? +} + +fn foo(x: Result<!, i32>) -> Result<u32, i32> { + let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; + //~^ WARN unreachable pattern + //~| WARN unreachable expression + Ok(y) +} + +fn qux(x: Result<u32, Void>) -> Result<u32, i32> { + Ok(x?) +} + +fn vom(x: Result<u32, Void>) -> Result<u32, i32> { + let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?; + //~^ WARN unreachable pattern + Ok(y) +} + + +fn main() { + let _ = bar(Err(123)); + let _ = foo(Err(123)); + let _ = qux(Ok(123)); + let _ = vom(Ok(123)); +} diff --git a/src/test/ui/reachable/unreachable-try-pattern.stderr b/src/test/ui/reachable/unreachable-try-pattern.stderr new file mode 100644 index 000000000..8f3e23119 --- /dev/null +++ b/src/test/ui/reachable/unreachable-try-pattern.stderr @@ -0,0 +1,35 @@ +warning: unreachable expression + --> $DIR/unreachable-try-pattern.rs:19:36 + | +LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; + | -^^^^^^^ + | | + | unreachable expression + | any code following this expression is unreachable + | +note: the lint level is defined here + --> $DIR/unreachable-try-pattern.rs:3:9 + | +LL | #![warn(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +warning: unreachable pattern + --> $DIR/unreachable-try-pattern.rs:19:24 + | +LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/unreachable-try-pattern.rs:4:9 + | +LL | #![warn(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +warning: unreachable pattern + --> $DIR/unreachable-try-pattern.rs:30:40 + | +LL | let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?; + | ^^^^^^ + +warning: 3 warnings emitted + diff --git a/src/test/ui/reachable/unreachable-variant.rs b/src/test/ui/reachable/unreachable-variant.rs new file mode 100644 index 000000000..008c2d476 --- /dev/null +++ b/src/test/ui/reachable/unreachable-variant.rs @@ -0,0 +1,7 @@ +// aux-build:unreachable_variant.rs + +extern crate unreachable_variant as other; + +fn main() { + let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private +} diff --git a/src/test/ui/reachable/unreachable-variant.stderr b/src/test/ui/reachable/unreachable-variant.stderr new file mode 100644 index 000000000..6c27a2756 --- /dev/null +++ b/src/test/ui/reachable/unreachable-variant.stderr @@ -0,0 +1,15 @@ +error[E0603]: module `super_sekrit` is private + --> $DIR/unreachable-variant.rs:6:21 + | +LL | let _x = other::super_sekrit::sooper_sekrit::baz; + | ^^^^^^^^^^^^ private module + | +note: the module `super_sekrit` is defined here + --> $DIR/auxiliary/unreachable_variant.rs:1:1 + | +LL | mod super_sekrit { + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/reachable/unwarned-match-on-never.rs b/src/test/ui/reachable/unwarned-match-on-never.rs new file mode 100644 index 000000000..71f8fe3a7 --- /dev/null +++ b/src/test/ui/reachable/unwarned-match-on-never.rs @@ -0,0 +1,24 @@ +#![deny(unreachable_code)] +#![allow(dead_code)] + +#![feature(never_type)] + +fn foo(x: !) -> bool { + // Explicit matches on the never type are unwarned. + match x {} + // But matches in unreachable code are warned. + match x {} //~ ERROR unreachable expression +} + +fn bar() { + match (return) { + () => () //~ ERROR unreachable arm + } +} + +fn main() { + return; + match () { //~ ERROR unreachable expression + () => (), + } +} diff --git a/src/test/ui/reachable/unwarned-match-on-never.stderr b/src/test/ui/reachable/unwarned-match-on-never.stderr new file mode 100644 index 000000000..a296d2a05 --- /dev/null +++ b/src/test/ui/reachable/unwarned-match-on-never.stderr @@ -0,0 +1,35 @@ +error: unreachable expression + --> $DIR/unwarned-match-on-never.rs:10:5 + | +LL | match x {} + | - any code following this expression is unreachable +LL | // But matches in unreachable code are warned. +LL | match x {} + | ^^^^^^^^^^ unreachable expression + | +note: the lint level is defined here + --> $DIR/unwarned-match-on-never.rs:1:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable arm + --> $DIR/unwarned-match-on-never.rs:15:15 + | +LL | match (return) { + | -------- any code following this expression is unreachable +LL | () => () + | ^^ unreachable arm + +error: unreachable expression + --> $DIR/unwarned-match-on-never.rs:21:5 + | +LL | return; + | ------ any code following this expression is unreachable +LL | / match () { +LL | | () => (), +LL | | } + | |_____^ unreachable expression + +error: aborting due to 3 previous errors + |