diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/expr/if | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
43 files changed, 1110 insertions, 0 deletions
diff --git a/src/test/ui/expr/if-bot.rs b/src/test/ui/expr/if-bot.rs new file mode 100644 index 000000000..0f09db530 --- /dev/null +++ b/src/test/ui/expr/if-bot.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + let i: isize = if false { panic!() } else { 5 }; + println!("{}", i); +} diff --git a/src/test/ui/expr/if/attrs/bad-cfg.rs b/src/test/ui/expr/if/attrs/bad-cfg.rs new file mode 100644 index 000000000..3f84929a0 --- /dev/null +++ b/src/test/ui/expr/if/attrs/bad-cfg.rs @@ -0,0 +1,5 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + let _ = #[cfg(FALSE)] if true {}; //~ ERROR removing an expression +} diff --git a/src/test/ui/expr/if/attrs/bad-cfg.stderr b/src/test/ui/expr/if/attrs/bad-cfg.stderr new file mode 100644 index 000000000..8a2890886 --- /dev/null +++ b/src/test/ui/expr/if/attrs/bad-cfg.stderr @@ -0,0 +1,8 @@ +error: removing an expression is not supported in this position + --> $DIR/bad-cfg.rs:4:13 + | +LL | let _ = #[cfg(FALSE)] if true {}; + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/expr/if/attrs/builtin-if-attr.rs b/src/test/ui/expr/if/attrs/builtin-if-attr.rs new file mode 100644 index 000000000..7e2906615 --- /dev/null +++ b/src/test/ui/expr/if/attrs/builtin-if-attr.rs @@ -0,0 +1,12 @@ +// check-pass + +fn main() { + #[allow(unused_variables)] + if true { + let a = 1; + } else if false { + let b = 1; + } else { + let c = 1; + } +} diff --git a/src/test/ui/expr/if/attrs/cfg-false-if-attr.rs b/src/test/ui/expr/if/attrs/cfg-false-if-attr.rs new file mode 100644 index 000000000..1f77a1bb3 --- /dev/null +++ b/src/test/ui/expr/if/attrs/cfg-false-if-attr.rs @@ -0,0 +1,43 @@ +// check-pass + +#[cfg(FALSE)] +fn simple_attr() { + #[attr] if true {} + #[allow_warnings] if true {} +} + +#[cfg(FALSE)] +fn if_else_chain() { + #[first_attr] if true { + } else if false { + } else { + } +} + +#[cfg(FALSE)] +fn if_let() { + #[attr] if let Some(_) = Some(true) {} +} + +fn bar() { + #[cfg(FALSE)] + if true { + let x: () = true; // Should not error due to the #[cfg(FALSE)] + } + + #[cfg_attr(not(unset_attr), cfg(FALSE))] + if true { + let a: () = true; // Should not error due to the applied #[cfg(FALSE)] + } +} + +macro_rules! custom_macro { + ($expr:expr) => {} +} + +custom_macro! { + #[attr] if true {} +} + + +fn main() {} diff --git a/src/test/ui/expr/if/attrs/else-attrs.rs b/src/test/ui/expr/if/attrs/else-attrs.rs new file mode 100644 index 000000000..85da7cf6b --- /dev/null +++ b/src/test/ui/expr/if/attrs/else-attrs.rs @@ -0,0 +1,25 @@ +#[cfg(FALSE)] +fn if_else_parse_error() { + if true { + } #[attr] else if false { //~ ERROR expected + } +} + +#[cfg(FALSE)] +fn else_attr_ifparse_error() { + if true { + } else #[attr] if false { //~ ERROR outer attributes are not allowed + } else { + } +} + +#[cfg(FALSE)] +fn else_parse_error() { + if true { + } else if false { + } #[attr] else { //~ ERROR expected + } +} + +fn main() { +} diff --git a/src/test/ui/expr/if/attrs/else-attrs.stderr b/src/test/ui/expr/if/attrs/else-attrs.stderr new file mode 100644 index 000000000..273337705 --- /dev/null +++ b/src/test/ui/expr/if/attrs/else-attrs.stderr @@ -0,0 +1,26 @@ +error: expected expression, found keyword `else` + --> $DIR/else-attrs.rs:4:15 + | +LL | } #[attr] else if false { + | ^^^^ expected expression + +error: outer attributes are not allowed on `if` and `else` branches + --> $DIR/else-attrs.rs:11:12 + | +LL | } else #[attr] if false { + | _______----_^^^^^^^_- + | | | | + | | | help: remove the attributes + | | the branch belongs to this `else` +LL | | } else { +LL | | } + | |_____- the attributes are attached to this branch + +error: expected expression, found keyword `else` + --> $DIR/else-attrs.rs:20:15 + | +LL | } #[attr] else { + | ^^^^ expected expression + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/expr/if/attrs/gate-whole-expr.rs b/src/test/ui/expr/if/attrs/gate-whole-expr.rs new file mode 100644 index 000000000..63772d54b --- /dev/null +++ b/src/test/ui/expr/if/attrs/gate-whole-expr.rs @@ -0,0 +1,15 @@ +// run-pass + +fn main() { + let x = 1; + + #[cfg(FALSE)] + if false { + x = 2; + } else if true { + x = 3; + } else { + x = 4; + } + assert_eq!(x, 1); +} diff --git a/src/test/ui/expr/if/attrs/let-chains-attr.rs b/src/test/ui/expr/if/attrs/let-chains-attr.rs new file mode 100644 index 000000000..2cd873114 --- /dev/null +++ b/src/test/ui/expr/if/attrs/let-chains-attr.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(let_chains)] + +#[cfg(FALSE)] +fn foo() { + #[attr] + if let Some(_) = Some(true) && let Ok(_) = Ok(1) { + } else if let Some(false) = Some(true) { + } +} + +fn main() {} diff --git a/src/test/ui/expr/if/attrs/stmt-expr-gated.rs b/src/test/ui/expr/if/attrs/stmt-expr-gated.rs new file mode 100644 index 000000000..38599c8e6 --- /dev/null +++ b/src/test/ui/expr/if/attrs/stmt-expr-gated.rs @@ -0,0 +1,6 @@ +fn main() { + let _ = #[deny(warnings)] if true { //~ ERROR attributes on expressions + } else if false { + } else { + }; +} diff --git a/src/test/ui/expr/if/attrs/stmt-expr-gated.stderr b/src/test/ui/expr/if/attrs/stmt-expr-gated.stderr new file mode 100644 index 000000000..47dac39a9 --- /dev/null +++ b/src/test/ui/expr/if/attrs/stmt-expr-gated.stderr @@ -0,0 +1,12 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/stmt-expr-gated.rs:2:13 + | +LL | let _ = #[deny(warnings)] if true { + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information + = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.rs b/src/test/ui/expr/if/bad-if-let-suggestion.rs new file mode 100644 index 000000000..a8b2a2830 --- /dev/null +++ b/src/test/ui/expr/if/bad-if-let-suggestion.rs @@ -0,0 +1,24 @@ +// FIXME(compiler-errors): This really should suggest `let` on the RHS of the +// `&&` operator, but that's kinda hard to do because of precedence. +// Instead, for now we just make sure not to suggest `if let let`. +fn a() { + if let x = 1 && i = 2 {} + //~^ ERROR cannot find value `i` in this scope + //~| ERROR `let` expressions in this position are unstable + //~| ERROR mismatched types + //~| ERROR `let` expressions are not supported here +} + +fn b() { + if (i + j) = i {} + //~^ ERROR cannot find value `i` in this scope + //~| ERROR cannot find value `i` in this scope + //~| ERROR cannot find value `j` in this scope +} + +fn c() { + if x[0] = 1 {} + //~^ ERROR cannot find value `x` in this scope +} + +fn main() {} diff --git a/src/test/ui/expr/if/bad-if-let-suggestion.stderr b/src/test/ui/expr/if/bad-if-let-suggestion.stderr new file mode 100644 index 000000000..60d286fed --- /dev/null +++ b/src/test/ui/expr/if/bad-if-let-suggestion.stderr @@ -0,0 +1,69 @@ +error: `let` expressions are not supported here + --> $DIR/bad-if-let-suggestion.rs:5:8 + | +LL | if let x = 1 && i = 2 {} + | ^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error[E0425]: cannot find value `i` in this scope + --> $DIR/bad-if-let-suggestion.rs:5:21 + | +LL | if let x = 1 && i = 2 {} + | ^ not found in this scope + +error[E0425]: cannot find value `i` in this scope + --> $DIR/bad-if-let-suggestion.rs:13:9 + | +LL | fn a() { + | ------ similarly named function `a` defined here +... +LL | if (i + j) = i {} + | ^ help: a function with a similar name exists: `a` + +error[E0425]: cannot find value `j` in this scope + --> $DIR/bad-if-let-suggestion.rs:13:13 + | +LL | fn a() { + | ------ similarly named function `a` defined here +... +LL | if (i + j) = i {} + | ^ help: a function with a similar name exists: `a` + +error[E0425]: cannot find value `i` in this scope + --> $DIR/bad-if-let-suggestion.rs:13:18 + | +LL | fn a() { + | ------ similarly named function `a` defined here +... +LL | if (i + j) = i {} + | ^ help: a function with a similar name exists: `a` + +error[E0425]: cannot find value `x` in this scope + --> $DIR/bad-if-let-suggestion.rs:20:8 + | +LL | fn a() { + | ------ similarly named function `a` defined here +... +LL | if x[0] = 1 {} + | ^ help: a function with a similar name exists: `a` + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/bad-if-let-suggestion.rs:5:8 + | +LL | if let x = 1 && i = 2 {} + | ^^^^^^^^^ + | + = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error[E0308]: mismatched types + --> $DIR/bad-if-let-suggestion.rs:5:8 + | +LL | if let x = 1 && i = 2 {} + | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0425, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/expr-if-panic-fn.rs b/src/test/ui/expr/if/expr-if-panic-fn.rs new file mode 100644 index 000000000..36e49785a --- /dev/null +++ b/src/test/ui/expr/if/expr-if-panic-fn.rs @@ -0,0 +1,20 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn f() -> ! { + panic!() +} + +fn g() -> isize { + let x = if true { + f() + } else { + 10 + }; + return x; +} + +fn main() { + g(); +} diff --git a/src/test/ui/expr/if/expr-if-panic-pass.rs b/src/test/ui/expr/if/expr-if-panic-pass.rs new file mode 100644 index 000000000..6069cd835 --- /dev/null +++ b/src/test/ui/expr/if/expr-if-panic-pass.rs @@ -0,0 +1,18 @@ +// run-pass + +fn test_if_panic() { + let x = if false { panic!() } else { 10 }; + assert_eq!(x, 10); +} + +fn test_else_panic() { + let x = if true { 10 } else { panic!() }; + assert_eq!(x, 10); +} + +fn test_elseif_panic() { + let x = if false { 0 } else if false { panic!() } else { 10 }; + assert_eq!(x, 10); +} + +pub fn main() { test_if_panic(); test_else_panic(); test_elseif_panic(); } diff --git a/src/test/ui/expr/if/expr-if-panic.rs b/src/test/ui/expr/if/expr-if-panic.rs new file mode 100644 index 000000000..520ee0870 --- /dev/null +++ b/src/test/ui/expr/if/expr-if-panic.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn main() { + let _x = if false { + 0 + } else if true { + panic!() + } else { + 10 + }; +} diff --git a/src/test/ui/expr/if/expr-if.rs b/src/test/ui/expr/if/expr-if.rs new file mode 100644 index 000000000..2b8474ff4 --- /dev/null +++ b/src/test/ui/expr/if/expr-if.rs @@ -0,0 +1,52 @@ +// run-pass +// Tests for if as expressions + +fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); } + +fn test_else() { + let rs: bool = if false { false } else { true }; + assert!((rs)); +} + +fn test_elseif1() { + let rs: bool = if true { true } else if true { false } else { false }; + assert!((rs)); +} + +fn test_elseif2() { + let rs: bool = if false { false } else if true { true } else { false }; + assert!((rs)); +} + +fn test_elseif3() { + let rs: bool = if false { false } else if false { false } else { true }; + assert!((rs)); +} + +fn test_inferrence() { + let rs = if true { true } else { false }; + assert!((rs)); +} + +fn test_if_as_if_condition() { + let rs1 = if if false { false } else { true } { true } else { false }; + assert!((rs1)); + let rs2 = if if true { false } else { true } { false } else { true }; + assert!((rs2)); +} + +fn test_if_as_block_result() { + let rs = if true { if false { false } else { true } } else { false }; + assert!((rs)); +} + +pub fn main() { + test_if(); + test_else(); + test_elseif1(); + test_elseif2(); + test_elseif3(); + test_inferrence(); + test_if_as_if_condition(); + test_if_as_block_result(); +} diff --git a/src/test/ui/expr/if/if-branch-types.rs b/src/test/ui/expr/if/if-branch-types.rs new file mode 100644 index 000000000..c125ba306 --- /dev/null +++ b/src/test/ui/expr/if/if-branch-types.rs @@ -0,0 +1,5 @@ +fn main() { + let x = if true { 10i32 } else { 10u32 }; + //~^ ERROR `if` and `else` have incompatible types + //~| expected `i32`, found `u32` +} diff --git a/src/test/ui/expr/if/if-branch-types.stderr b/src/test/ui/expr/if/if-branch-types.stderr new file mode 100644 index 000000000..14f02163a --- /dev/null +++ b/src/test/ui/expr/if/if-branch-types.stderr @@ -0,0 +1,11 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-branch-types.rs:2:38 + | +LL | let x = if true { 10i32 } else { 10u32 }; + | ----- ^^^^^ expected `i32`, found `u32` + | | + | expected because of this + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/if-check-panic.rs b/src/test/ui/expr/if/if-check-panic.rs new file mode 100644 index 000000000..037cd427c --- /dev/null +++ b/src/test/ui/expr/if/if-check-panic.rs @@ -0,0 +1,25 @@ +// run-fail +// error-pattern:Number is odd +// ignore-emscripten no processes + +fn even(x: usize) -> bool { + if x < 2 { + return false; + } else if x == 2 { + return true; + } else { + return even(x - 2); + } +} + +fn foo(x: usize) { + if even(x) { + println!("{}", x); + } else { + panic!("Number is odd"); + } +} + +fn main() { + foo(3); +} diff --git a/src/test/ui/expr/if/if-check.rs b/src/test/ui/expr/if/if-check.rs new file mode 100644 index 000000000..6593225e7 --- /dev/null +++ b/src/test/ui/expr/if/if-check.rs @@ -0,0 +1,17 @@ +// run-pass + +fn even(x: usize) -> bool { + if x < 2 { + return false; + } else if x == 2 { return true; } else { return even(x - 2); } +} + +fn foo(x: usize) { + if even(x) { + println!("{}", x); + } else { + panic!(); + } +} + +pub fn main() { foo(2); } diff --git a/src/test/ui/expr/if/if-cond-bot.rs b/src/test/ui/expr/if/if-cond-bot.rs new file mode 100644 index 000000000..bcd114678 --- /dev/null +++ b/src/test/ui/expr/if/if-cond-bot.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn my_err(s: String) -> ! { + println!("{}", s); + panic!("quux"); +} + +fn main() { + if my_err("bye".to_string()) { + } +} diff --git a/src/test/ui/expr/if/if-else-type-mismatch.rs b/src/test/ui/expr/if/if-else-type-mismatch.rs new file mode 100644 index 000000000..1a0a36df2 --- /dev/null +++ b/src/test/ui/expr/if/if-else-type-mismatch.rs @@ -0,0 +1,46 @@ +fn main() { + let _ = if true { + 1i32 + } else { + 2u32 + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { 42i32 } else { 42u32 }; + //~^ ERROR `if` and `else` have incompatible types + let _ = if true { + 3u32; + } else { + 4u32 + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { + 5u32 + } else { + 6u32; + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { + 7i32; + } else { + 8u32 + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { + 9i32 + } else { + 10u32; + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { + + } else { + 11u32 + }; + //~^^ ERROR `if` and `else` have incompatible types + let _ = if true { + 12i32 + } else { + + }; + //~^^^ ERROR `if` and `else` have incompatible types +} diff --git a/src/test/ui/expr/if/if-else-type-mismatch.stderr b/src/test/ui/expr/if/if-else-type-mismatch.stderr new file mode 100644 index 000000000..9fa190d6c --- /dev/null +++ b/src/test/ui/expr/if/if-else-type-mismatch.stderr @@ -0,0 +1,106 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:5:9 + | +LL | let _ = if true { + | _____________- +LL | | 1i32 + | | ---- expected because of this +LL | | } else { +LL | | 2u32 + | | ^^^^ expected `i32`, found `u32` +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:8:38 + | +LL | let _ = if true { 42i32 } else { 42u32 }; + | ----- ^^^^^ expected `i32`, found `u32` + | | + | expected because of this + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:13:9 + | +LL | let _ = if true { + | _____________- +LL | | 3u32; + | | ----- + | | | | + | | | help: consider removing this semicolon + | | expected because of this +LL | | } else { +LL | | 4u32 + | | ^^^^ expected `()`, found `u32` +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:19:9 + | +LL | let _ = if true { + | _____________- +LL | | 5u32 + | | ---- expected because of this +LL | | } else { +LL | | 6u32; + | | ^^^^- + | | | | + | | | help: consider removing this semicolon + | | expected `u32`, found `()` +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:25:9 + | +LL | let _ = if true { + | _____________- +LL | | 7i32; + | | ----- expected because of this +LL | | } else { +LL | | 8u32 + | | ^^^^ expected `()`, found `u32` +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:31:9 + | +LL | let _ = if true { + | _____________- +LL | | 9i32 + | | ---- expected because of this +LL | | } else { +LL | | 10u32; + | | ^^^^^^ expected `i32`, found `()` +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:37:9 + | +LL | let _ = if true { + | _____________________- +LL | | +LL | | } else { + | |_____- expected because of this +LL | 11u32 + | ^^^^^ expected `()`, found `u32` + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-else-type-mismatch.rs:42:12 + | +LL | let _ = if true { + | ------- `if` and `else` have incompatible types +LL | 12i32 + | ----- expected because of this +LL | } else { + | ____________^ +LL | | +LL | | }; + | |_____^ expected `i32`, found `()` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/if-let-arm-types.rs b/src/test/ui/expr/if/if-let-arm-types.rs new file mode 100644 index 000000000..1e8260a01 --- /dev/null +++ b/src/test/ui/expr/if/if-let-arm-types.rs @@ -0,0 +1,11 @@ +fn main() { + if let Some(b) = None { + //~^ NOTE `if` and `else` have incompatible types + () + //~^ NOTE expected because of this + } else { + 1 + }; + //~^^ ERROR: `if` and `else` have incompatible types + //~| NOTE expected `()`, found integer +} diff --git a/src/test/ui/expr/if/if-let-arm-types.stderr b/src/test/ui/expr/if/if-let-arm-types.stderr new file mode 100644 index 000000000..b40a0f479 --- /dev/null +++ b/src/test/ui/expr/if/if-let-arm-types.stderr @@ -0,0 +1,17 @@ +error[E0308]: `if` and `else` have incompatible types + --> $DIR/if-let-arm-types.rs:7:9 + | +LL | / if let Some(b) = None { +LL | | +LL | | () + | | -- expected because of this +LL | | +LL | | } else { +LL | | 1 + | | ^ expected `()`, found integer +LL | | }; + | |_____- `if` and `else` have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/if-let.rs b/src/test/ui/expr/if/if-let.rs new file mode 100644 index 000000000..7fdd2be95 --- /dev/null +++ b/src/test/ui/expr/if/if-let.rs @@ -0,0 +1,49 @@ +// check-pass + +fn macros() { + macro_rules! foo { + ($p:pat, $e:expr, $b:block) => {{ + if let $p = $e $b + //~^ WARN irrefutable `if let` + //~| WARN irrefutable `if let` + }} + } + macro_rules! bar{ + ($p:pat, $e:expr, $b:block) => {{ + foo!($p, $e, $b) + }} + } + + foo!(a, 1, { + println!("irrefutable pattern"); + }); + bar!(a, 1, { + println!("irrefutable pattern"); + }); +} + +pub fn main() { + if let a = 1 { //~ WARN irrefutable `if let` + println!("irrefutable pattern"); + } + + if let a = 1 { //~ WARN irrefutable `if let` + println!("irrefutable pattern"); + } else if true { + println!("else-if in irrefutable `if let`"); + } else { + println!("else in irrefutable `if let`"); + } + + if let 1 = 2 { + println!("refutable pattern"); + } else if let a = 1 { //~ WARN irrefutable `if let` + println!("irrefutable pattern"); + } + + if true { + println!("if"); + } else if let a = 1 { //~ WARN irrefutable `if let` + println!("irrefutable pattern"); + } +} diff --git a/src/test/ui/expr/if/if-let.stderr b/src/test/ui/expr/if/if-let.stderr new file mode 100644 index 000000000..8238b3f0e --- /dev/null +++ b/src/test/ui/expr/if/if-let.stderr @@ -0,0 +1,69 @@ +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:6:16 + | +LL | if let $p = $e $b + | ^^^ +... +LL | / foo!(a, 1, { +LL | | println!("irrefutable pattern"); +LL | | }); + | |______- in this macro invocation + | + = note: `#[warn(irrefutable_let_patterns)]` on by default + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:6:16 + | +LL | if let $p = $e $b + | ^^^ +... +LL | / bar!(a, 1, { +LL | | println!("irrefutable pattern"); +LL | | }); + | |______- in this macro invocation + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + = note: this warning originates in the macro `foo` which comes from the expansion of the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:26:8 + | +LL | if let a = 1 { + | ^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:30:8 + | +LL | if let a = 1 { + | ^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:40:15 + | +LL | } else if let a = 1 { + | ^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + +warning: irrefutable `if let` pattern + --> $DIR/if-let.rs:46:15 + | +LL | } else if let a = 1 { + | ^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + +warning: 6 warnings emitted + diff --git a/src/test/ui/expr/if/if-loop.rs b/src/test/ui/expr/if/if-loop.rs new file mode 100644 index 000000000..06d0bdf45 --- /dev/null +++ b/src/test/ui/expr/if/if-loop.rs @@ -0,0 +1,8 @@ +// check-pass + +// This used to ICE because the "if" being unreachable was not handled correctly +fn err() { + if loop {} {} +} + +fn main() {} diff --git a/src/test/ui/expr/if/if-no-match-bindings.rs b/src/test/ui/expr/if/if-no-match-bindings.rs new file mode 100644 index 000000000..ca3df0fdd --- /dev/null +++ b/src/test/ui/expr/if/if-no-match-bindings.rs @@ -0,0 +1,28 @@ +// Checks for `if` expressions with respect to default match bindings. +// Specifically, we do not accept `if cond { ... }` where `cond: &mut? bool`. +// Meanwhile, `match cond { true => ..., _ => ... }` does accept that. + +// FIXME(@rust-lang/lang-team): consider relaxing this? + +fn b_ref<'a>() -> &'a bool { &true } +fn b_mut_ref<'a>() -> &'a mut bool { &mut true } + +fn main() { + // This is OK: + match b_ref() { true => {}, _ => {} } + match b_mut_ref() { true => {}, _ => {} } + match &true { true => {}, _ => {} } + match &mut true { true => {}, _ => {} } + + // This is NOT: + if b_ref() {} //~ ERROR mismatched types [E0308] + if b_mut_ref() {} //~ ERROR mismatched types [E0308] + if &true {} //~ ERROR mismatched types [E0308] + if &mut true {} //~ ERROR mismatched types [E0308] + + // This is also NOT: + while b_ref() {} //~ ERROR mismatched types [E0308] + while b_mut_ref() {} //~ ERROR mismatched types [E0308] + while &true {} //~ ERROR mismatched types [E0308] + while &mut true {} //~ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/expr/if/if-no-match-bindings.stderr b/src/test/ui/expr/if/if-no-match-bindings.stderr new file mode 100644 index 000000000..737a5d604 --- /dev/null +++ b/src/test/ui/expr/if/if-no-match-bindings.stderr @@ -0,0 +1,95 @@ +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:18:8 + | +LL | if b_ref() {} + | ^^^^^^^ expected `bool`, found `&bool` + | +help: consider dereferencing the borrow + | +LL | if *b_ref() {} + | + + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:19:8 + | +LL | if b_mut_ref() {} + | ^^^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider dereferencing the borrow + | +LL | if *b_mut_ref() {} + | + + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:20:8 + | +LL | if &true {} + | ^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL - if &true {} +LL + if true {} + | + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:21:8 + | +LL | if &mut true {} + | ^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider removing the borrow + | +LL - if &mut true {} +LL + if true {} + | + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:24:11 + | +LL | while b_ref() {} + | ^^^^^^^ expected `bool`, found `&bool` + | +help: consider dereferencing the borrow + | +LL | while *b_ref() {} + | + + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:25:11 + | +LL | while b_mut_ref() {} + | ^^^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider dereferencing the borrow + | +LL | while *b_mut_ref() {} + | + + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:26:11 + | +LL | while &true {} + | ^^^^^ expected `bool`, found `&bool` + | +help: consider removing the borrow + | +LL - while &true {} +LL + while true {} + | + +error[E0308]: mismatched types + --> $DIR/if-no-match-bindings.rs:27:11 + | +LL | while &mut true {} + | ^^^^^^^^^ expected `bool`, found `&mut bool` + | +help: consider removing the borrow + | +LL - while &mut true {} +LL + while true {} + | + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/if-ret.rs b/src/test/ui/expr/if/if-ret.rs new file mode 100644 index 000000000..896072ce7 --- /dev/null +++ b/src/test/ui/expr/if/if-ret.rs @@ -0,0 +1,8 @@ +// run-pass + +#![allow(unused_parens)] +// pretty-expanded FIXME #23616 + +fn foo() { if (return) { } } //~ WARNING unreachable block in `if` + +pub fn main() { foo(); } diff --git a/src/test/ui/expr/if/if-ret.stderr b/src/test/ui/expr/if/if-ret.stderr new file mode 100644 index 000000000..8ced271aa --- /dev/null +++ b/src/test/ui/expr/if/if-ret.stderr @@ -0,0 +1,12 @@ +warning: unreachable block in `if` or `while` expression + --> $DIR/if-ret.rs:6:24 + | +LL | fn foo() { if (return) { } } + | -------- ^^^ unreachable block in `if` or `while` expression + | | + | any code following this expression is unreachable + | + = note: `#[warn(unreachable_code)]` on by default + +warning: 1 warning emitted + diff --git a/src/test/ui/expr/if/if-typeck.rs b/src/test/ui/expr/if/if-typeck.rs new file mode 100644 index 000000000..d8c262bd6 --- /dev/null +++ b/src/test/ui/expr/if/if-typeck.rs @@ -0,0 +1,10 @@ +// error-pattern:mismatched types +// issue #513 + +fn f() { } + +fn main() { + + // f is not a bool + if f { } +} diff --git a/src/test/ui/expr/if/if-typeck.stderr b/src/test/ui/expr/if/if-typeck.stderr new file mode 100644 index 000000000..74ed0ed0a --- /dev/null +++ b/src/test/ui/expr/if/if-typeck.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/if-typeck.rs:9:8 + | +LL | if f { } + | ^ expected `bool`, found fn item + | + = note: expected type `bool` + found fn item `fn() {f}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/expr/if/if-without-block.rs b/src/test/ui/expr/if/if-without-block.rs new file mode 100644 index 000000000..5add9dfda --- /dev/null +++ b/src/test/ui/expr/if/if-without-block.rs @@ -0,0 +1,7 @@ +fn main() { + let n = 1; + if 5 == { + //~^ ERROR this `if` expression is missing a block after the condition + println!("five"); + } +} diff --git a/src/test/ui/expr/if/if-without-block.stderr b/src/test/ui/expr/if/if-without-block.stderr new file mode 100644 index 000000000..2d1ee04ce --- /dev/null +++ b/src/test/ui/expr/if/if-without-block.stderr @@ -0,0 +1,14 @@ +error: this `if` expression is missing a block after the condition + --> $DIR/if-without-block.rs:3:5 + | +LL | if 5 == { + | ^^ + | +help: this binary operation is possibly unfinished + --> $DIR/if-without-block.rs:3:8 + | +LL | if 5 == { + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/expr/if/if-without-else-as-fn-expr.rs b/src/test/ui/expr/if/if-without-else-as-fn-expr.rs new file mode 100644 index 000000000..19fbfb27b --- /dev/null +++ b/src/test/ui/expr/if/if-without-else-as-fn-expr.rs @@ -0,0 +1,49 @@ +fn foo(bar: usize) -> usize { + if bar % 5 == 0 { + return 3; + } + //~^^^ ERROR `if` may be missing an `else` clause +} + +fn foo2(bar: usize) -> usize { + let x: usize = if bar % 5 == 0 { + return 3; + }; + //~^^^ ERROR `if` may be missing an `else` clause + x +} + +fn foo3(bar: usize) -> usize { + if bar % 5 == 0 { + 3 + } + //~^^^ ERROR `if` may be missing an `else` clause +} + +fn foo_let(bar: usize) -> usize { + if let 0 = 1 { + return 3; + } + //~^^^ ERROR `if` may be missing an `else` clause +} + +fn foo2_let(bar: usize) -> usize { + let x: usize = if let 0 = 1 { + return 3; + }; + //~^^^ ERROR `if` may be missing an `else` clause + x +} + +fn foo3_let(bar: usize) -> usize { + if let 0 = 1 { + 3 + } + //~^^^ ERROR `if` may be missing an `else` clause +} + +// FIXME(60254): deduplicate first error in favor of second. + +fn main() { + let _ = foo(1); +} diff --git a/src/test/ui/expr/if/if-without-else-as-fn-expr.stderr b/src/test/ui/expr/if/if-without-else-as-fn-expr.stderr new file mode 100644 index 000000000..4daf27493 --- /dev/null +++ b/src/test/ui/expr/if/if-without-else-as-fn-expr.stderr @@ -0,0 +1,83 @@ +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:2:5 + | +LL | fn foo(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if bar % 5 == 0 { +LL | | return 3; +LL | | } + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:9:20 + | +LL | let x: usize = if bar % 5 == 0 { + | _________-__________^ + | | | + | | expected because of this assignment +LL | | return 3; +LL | | }; + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:17:5 + | +LL | fn foo3(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if bar % 5 == 0 { +LL | | 3 +LL | | } + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:24:5 + | +LL | fn foo_let(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if let 0 = 1 { +LL | | return 3; +LL | | } + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:31:20 + | +LL | let x: usize = if let 0 = 1 { + | _________-__________^ + | | | + | | expected because of this assignment +LL | | return 3; +LL | | }; + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-as-fn-expr.rs:39:5 + | +LL | fn foo3_let(bar: usize) -> usize { + | ----- expected `usize` because of this return type +LL | / if let 0 = 1 { +LL | | 3 +LL | | } + | |_____^ expected `usize`, found `()` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0317`. diff --git a/src/test/ui/expr/if/if-without-else-result.rs b/src/test/ui/expr/if/if-without-else-result.rs new file mode 100644 index 000000000..cf84a99e5 --- /dev/null +++ b/src/test/ui/expr/if/if-without-else-result.rs @@ -0,0 +1,6 @@ +fn main() { + let a = if true { true }; + //~^ ERROR `if` may be missing an `else` clause [E0317] + //~| expected `()`, found `bool` + println!("{}", a); +} diff --git a/src/test/ui/expr/if/if-without-else-result.stderr b/src/test/ui/expr/if/if-without-else-result.stderr new file mode 100644 index 000000000..821635d37 --- /dev/null +++ b/src/test/ui/expr/if/if-without-else-result.stderr @@ -0,0 +1,15 @@ +error[E0317]: `if` may be missing an `else` clause + --> $DIR/if-without-else-result.rs:2:13 + | +LL | let a = if true { true }; + | ^^^^^^^^^^----^^ + | | | + | | found here + | expected `()`, found `bool` + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0317`. diff --git a/src/test/ui/expr/if/issue-4201.rs b/src/test/ui/expr/if/issue-4201.rs new file mode 100644 index 000000000..1f292229f --- /dev/null +++ b/src/test/ui/expr/if/issue-4201.rs @@ -0,0 +1,9 @@ +fn main() { + let a = if true { + 0 + } else if false { +//~^ ERROR `if` may be missing an `else` clause +//~| expected `()`, found integer + 1 + }; +} diff --git a/src/test/ui/expr/if/issue-4201.stderr b/src/test/ui/expr/if/issue-4201.stderr new file mode 100644 index 000000000..bc638ddf5 --- /dev/null +++ b/src/test/ui/expr/if/issue-4201.stderr @@ -0,0 +1,18 @@ +error[E0317]: `if` may be missing an `else` clause + --> $DIR/issue-4201.rs:4:12 + | +LL | } else if false { + | ____________^ +LL | | +LL | | +LL | | 1 + | | - found here +LL | | }; + | |_____^ expected `()`, found integer + | + = note: `if` expressions without `else` evaluate to `()` + = help: consider adding an `else` block that evaluates to the expected type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0317`. |