| // Check that we don't suggest enabling a feature for code that's |
| // not accepted even with that feature. |
| |
| #![allow(irrefutable_let_patterns)] |
| |
| use std::ops::Range; |
| |
| fn main() {} |
| |
| fn _if() { |
| if (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if (((let 0 = 1))) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if (let 0 = 1) && true {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if true && (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if (let 0 = 1) && (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| |
| if (let 2 = 3 && let 3 = 4 && let 4 = 5) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| } |
| |
| fn _while() { |
| while (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while (((let 0 = 1))) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while (let 0 = 1) && true {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while true && (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while (let 0 = 1) && (let 0 = 1) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| |
| while (let 2 = 3 && let 3 = 4 && let 4 = 5) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| } |
| |
| fn _macros() { |
| macro_rules! use_expr { |
| ($e:expr) => { |
| if $e {} |
| while $e {} |
| } |
| } |
| use_expr!((let 0 = 1 && 0 == 0)); |
| //~^ ERROR expected expression, found `let` statement |
| use_expr!((let 0 = 1)); |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| fn nested_within_if_expr() { |
| if &let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if !let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| if *let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| if -let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| fn _check_try_binds_tighter() -> Result<(), ()> { |
| if let 0 = 0? {} |
| //~^ ERROR the `?` operator can only be applied to values that implement `Try` |
| Ok(()) |
| } |
| if (let 0 = 0)? {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if true || let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| if (true || let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| if true && (true || let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| if true || (true && let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| let mut x = true; |
| if x = let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| if true..(let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| if ..(let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| if (let 0 = 0).. {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| // Binds as `(let ... = true)..true &&/|| false`. |
| if let Range { start: _, end: _ } = true..true && false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| if let Range { start: _, end: _ } = true..true || false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| // Binds as `(let Range { start: F, end } = F)..(|| true)`. |
| const F: fn() -> bool = || true; |
| if let Range { start: F, end } = F..|| true {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| // Binds as `(let Range { start: true, end } = t)..(&&false)`. |
| let t = &&true; |
| if let Range { start: true, end } = t..&&false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| if let true = let true = true {} |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| fn nested_within_while_expr() { |
| while &let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while !let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| while *let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| while -let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| fn _check_try_binds_tighter() -> Result<(), ()> { |
| while let 0 = 0? {} |
| //~^ ERROR the `?` operator can only be applied to values that implement `Try` |
| Ok(()) |
| } |
| while (let 0 = 0)? {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while true || let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| while (true || let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| while true && (true || let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| while true || (true && let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| let mut x = true; |
| while x = let 0 = 0 {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| while true..(let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| while ..(let 0 = 0) {} |
| //~^ ERROR expected expression, found `let` statement |
| while (let 0 = 0).. {} |
| //~^ ERROR expected expression, found `let` statement |
| |
| // Binds as `(let ... = true)..true &&/|| false`. |
| while let Range { start: _, end: _ } = true..true && false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| while let Range { start: _, end: _ } = true..true || false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| // Binds as `(let Range { start: F, end } = F)..(|| true)`. |
| const F: fn() -> bool = || true; |
| while let Range { start: F, end } = F..|| true {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| // Binds as `(let Range { start: true, end } = t)..(&&false)`. |
| let t = &&true; |
| while let Range { start: true, end } = t..&&false {} |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR mismatched types |
| |
| while let true = let true = true {} |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| fn not_error_because_clarified_intent() { |
| if let Range { start: _, end: _ } = (true..true || false) { } |
| |
| if let Range { start: _, end: _ } = (true..true && false) { } |
| |
| while let Range { start: _, end: _ } = (true..true || false) { } |
| |
| while let Range { start: _, end: _ } = (true..true && false) { } |
| } |
| |
| fn outside_if_and_while_expr() { |
| &let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| |
| !let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| *let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| -let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| let _ = let _ = 3; |
| //~^ ERROR expected expression, found `let` statement |
| |
| fn _check_try_binds_tighter() -> Result<(), ()> { |
| let 0 = 0?; |
| //~^ ERROR the `?` operator can only be applied to values that implement `Try` |
| Ok(()) |
| } |
| (let 0 = 0)?; |
| //~^ ERROR expected expression, found `let` statement |
| |
| true || let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| (true || let 0 = 0); |
| //~^ ERROR expected expression, found `let` statement |
| true && (true || let 0 = 0); |
| //~^ ERROR expected expression, found `let` statement |
| |
| let mut x = true; |
| x = let 0 = 0; |
| //~^ ERROR expected expression, found `let` statement |
| |
| true..(let 0 = 0); |
| //~^ ERROR expected expression, found `let` statement |
| ..(let 0 = 0); |
| //~^ ERROR expected expression, found `let` statement |
| (let 0 = 0)..; |
| //~^ ERROR expected expression, found `let` statement |
| |
| (let Range { start: _, end: _ } = true..true || false); |
| //~^ ERROR mismatched types |
| //~| ERROR expected expression, found `let` statement |
| |
| (let true = let true = true); |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| |
| { |
| #[cfg(FALSE)] |
| let x = true && let y = 1; |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| #[cfg(FALSE)] |
| { |
| [1, 2, 3][let _ = ()] |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| // Check function tail position. |
| &let 0 = 0 |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| // Let's make sure that `let` inside const generic arguments are considered. |
| fn inside_const_generic_arguments() { |
| struct A<const B: bool>; |
| impl<const B: bool> A<{B}> { const O: u32 = 5; } |
| |
| if let A::<{ |
| true && let 1 = 1 |
| //~^ ERROR expected expression, found `let` statement |
| }>::O = 5 {} |
| |
| while let A::<{ |
| true && let 1 = 1 |
| //~^ ERROR expected expression, found `let` statement |
| }>::O = 5 {} |
| |
| if A::<{ |
| true && let 1 = 1 |
| //~^ ERROR expected expression, found `let` statement |
| }>::O == 5 {} |
| |
| // In the cases above we have `ExprKind::Block` to help us out. |
| // Below however, we would not have a block and so an implementation might go |
| // from visiting expressions to types without banning `let` expressions down the tree. |
| // This tests ensures that we are not caught by surprise should the parser |
| // admit non-IDENT expressions in const generic arguments. |
| |
| if A::< |
| true && let 1 = 1 |
| //~^ ERROR expressions must be enclosed in braces |
| //~| ERROR expected expression, found `let` statement |
| >::O == 5 {} |
| } |
| |
| fn with_parenthesis() { |
| let opt = Some(Some(1i32)); |
| |
| if (let Some(a) = opt && true) { |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| if (let Some(a) = opt) && true { |
| //~^ ERROR expected expression, found `let` statement |
| } |
| if (let Some(a) = opt) && (let Some(b) = a) { |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| } |
| |
| if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| } |
| if (let Some(a) = opt && (let Some(b) = a)) && true { |
| //~^ ERROR expected expression, found `let` statement |
| //~| ERROR expected expression, found `let` statement |
| } |
| if (let Some(a) = opt && (true)) && true { |
| //~^ ERROR expected expression, found `let` statement |
| } |
| |
| #[cfg(FALSE)] |
| let x = (true && let y = 1); |
| //~^ ERROR expected expression, found `let` statement |
| |
| #[cfg(FALSE)] |
| { |
| ([1, 2, 3][let _ = ()]) |
| //~^ ERROR expected expression, found `let` statement |
| } |
| } |