From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rfc-2497-if-let-chains/disallowed-positions.rs | 480 +++++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs (limited to 'src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs') diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs new file mode 100644 index 000000000..2a9a5472b --- /dev/null +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -0,0 +1,480 @@ +// Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions. +// +// We want to make sure that `let` is banned in situations other than: +// +// expr = +// | ... +// | "if" expr_with_let block {"else" block}? +// | {label ":"}? while" expr_with_let block +// ; +// +// expr_with_let = +// | "let" top_pats "=" expr +// | expr_with_let "&&" expr_with_let +// | "(" expr_with_let ")" +// | expr +// ; +// +// To that end, we check some positions which is not part of the language above. + +#![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. + +#![allow(irrefutable_let_patterns)] + +use std::ops::Range; + +fn main() {} + +fn _if() { + if (let 0 = 1) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + if (((let 0 = 1))) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + if (let 0 = 1) && true {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + if true && (let 0 = 1) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + if (let 0 = 1) && (let 0 = 1) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + while (((let 0 = 1))) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + while (let 0 = 1) && true {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + while true && (let 0 = 1) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + while (let 0 = 1) && (let 0 = 1) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + use_expr!((let 0 = 1)); + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement +} + +fn nested_within_if_expr() { + if &let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + if !let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + if *let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR type `bool` cannot be dereferenced + //~| ERROR expected expression, found `let` statement + if -let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR cannot apply unary operator `-` to type `bool` + //~| 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 `let` expressions are not supported here + //~| ERROR the `?` operator can only be applied to values that implement `Try` + //~| ERROR the `?` operator can only be used in a function that returns `Result` + //~| ERROR expected expression, found `let` statement + + if true || let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + if (true || let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + if true && (true || let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + if true || (true && let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + let mut x = true; + if x = let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + if true..(let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + if ..(let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + if (let 0 = 0).. {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + // Binds as `(let ... = true)..true &&/|| false`. + if let Range { start: _, end: _ } = true..true && false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + if let Range { start: _, end: _ } = true..true || false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| 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 `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + if let Range { start: true, end } = t..&&false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types + + if let true = let true = true {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement +} + +fn nested_within_while_expr() { + while &let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + while !let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + while *let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR type `bool` cannot be dereferenced + //~| ERROR expected expression, found `let` statement + while -let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR cannot apply unary operator `-` to type `bool` + //~| 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 `let` expressions are not supported here + //~| ERROR the `?` operator can only be applied to values that implement `Try` + //~| ERROR the `?` operator can only be used in a function that returns `Result` + //~| ERROR expected expression, found `let` statement + + while true || let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + while (true || let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + while true && (true || let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + while true || (true && let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + let mut x = true; + while x = let 0 = 0 {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + while true..(let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + while ..(let 0 = 0) {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + while (let 0 = 0).. {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + // Binds as `(let ... = true)..true &&/|| false`. + while let Range { start: _, end: _ } = true..true && false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + while let Range { start: _, end: _ } = true..true || false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| 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 `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + while let Range { start: true, end } = t..&&false {} + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR mismatched types + //~| ERROR mismatched types + + while let true = let true = true {} + //~^ ERROR `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + !let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + *let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR type `bool` cannot be dereferenced + //~| ERROR expected expression, found `let` statement + -let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR cannot apply unary operator `-` to type `bool` + //~| 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 `let` expressions are not supported here + //~| ERROR the `?` operator can only be used in a function that returns `Result` + //~| ERROR the `?` operator can only be applied to values that implement `Try` + //~| ERROR expected expression, found `let` statement + + true || let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + (true || let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + true && (true || let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + let mut x = true; + x = let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + true..(let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + ..(let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + (let 0 = 0)..; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + + (let Range { start: _, end: _ } = true..true || false); + //~^ ERROR `let` expressions are not supported here + //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement + + (let true = let true = true); + //~^ ERROR `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| ERROR mismatched types + //~| 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; + impl A<{B}> { const O: u32 = 5; } + + if let A::<{ + true && let 1 = 1 + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + }>::O = 5 {} + + while let A::<{ + true && let 1 = 1 + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + }>::O = 5 {} + + if A::<{ + true && let 1 = 1 + //~^ ERROR `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| 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 `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + } + + if (let Some(a) = opt) && true { + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + } + if (let Some(a) = opt) && (let Some(b) = a) { + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + if let Some(a) = opt && (true && true) { + } + + if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + if (let Some(a) = opt && (let Some(b) = a)) && true { + //~^ ERROR `let` expressions are not supported here + //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + } + if (let Some(a) = opt && (true)) && true { + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + } + + if (true && (true)) && let Some(a) = opt { + } + if (true) && let Some(a) = opt { + } + if true && let Some(a) = opt { + } + + let fun = || true; + if let true = (true && fun()) && (true) { + } + + #[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 + } +} -- cgit v1.2.3