From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- .../ui/match/auxiliary/match_non_exhaustive_lib.rs | 5 + tests/ui/match/const_non_normal_zst_ref_pattern.rs | 9 ++ tests/ui/match/expr-match-panic-fn.rs | 19 ++++ tests/ui/match/expr-match-panic.rs | 10 ++ tests/ui/match/expr_before_ident_pat.rs | 13 +++ tests/ui/match/expr_before_ident_pat.stderr | 15 +++ tests/ui/match/guards.rs | 20 ++++ tests/ui/match/issue-11319.rs | 13 +++ tests/ui/match/issue-11319.stderr | 21 ++++ tests/ui/match/issue-11940.rs | 11 ++ tests/ui/match/issue-12552.rs | 11 ++ tests/ui/match/issue-12552.stderr | 34 ++++++ tests/ui/match/issue-18060.rs | 8 ++ tests/ui/match/issue-26251.rs | 15 +++ tests/ui/match/issue-26996.rs | 24 +++++ tests/ui/match/issue-27021.rs | 28 +++++ tests/ui/match/issue-33498.rs | 11 ++ tests/ui/match/issue-41255.rs | 50 +++++++++ tests/ui/match/issue-41255.stderr | 115 +++++++++++++++++++++ tests/ui/match/issue-42679.rs | 21 ++++ tests/ui/match/issue-46920-byte-array-patterns.rs | 28 +++++ tests/ui/match/issue-5530.rs | 40 +++++++ tests/ui/match/issue-56685.rs | 44 ++++++++ tests/ui/match/issue-56685.stderr | 63 +++++++++++ tests/ui/match/issue-70972-dyn-trait.rs | 10 ++ tests/ui/match/issue-70972-dyn-trait.stderr | 8 ++ tests/ui/match/issue-72680.rs | 63 +++++++++++ tests/ui/match/issue-72896.rs | 23 +++++ tests/ui/match/issue-74050-end-span.rs | 13 +++ tests/ui/match/issue-74050-end-span.stderr | 15 +++ tests/ui/match/issue-82392.rs | 9 ++ tests/ui/match/issue-82392.stdout | 16 +++ tests/ui/match/issue-82866.rs | 7 ++ tests/ui/match/issue-82866.stderr | 16 +++ tests/ui/match/issue-84434.rs | 18 ++++ tests/ui/match/issue-91058.rs | 11 ++ tests/ui/match/issue-91058.stderr | 11 ++ tests/ui/match/issue-92100.rs | 7 ++ tests/ui/match/issue-92100.stderr | 9 ++ tests/ui/match/match-arm-resolving-to-never.rs | 19 ++++ tests/ui/match/match-arm-resolving-to-never.stderr | 18 ++++ tests/ui/match/match-bot-panic.rs | 16 +++ tests/ui/match/match-disc-bot.rs | 16 +++ tests/ui/match/match-fn-call.rs | 12 +++ tests/ui/match/match-fn-call.stderr | 19 ++++ tests/ui/match/match-ill-type2.rs | 7 ++ tests/ui/match/match-ill-type2.stderr | 12 +++ tests/ui/match/match-incompat-type-semi.rs | 52 ++++++++++ tests/ui/match/match-incompat-type-semi.stderr | 88 ++++++++++++++++ tests/ui/match/match-join.rs | 11 ++ tests/ui/match/match-join.stderr | 9 ++ tests/ui/match/match-no-arms-unreachable-after.rs | 12 +++ .../match/match-no-arms-unreachable-after.stderr | 16 +++ tests/ui/match/match-on-negative-integer-ranges.rs | 7 ++ tests/ui/match/match-pattern-field-mismatch-2.rs | 16 +++ .../ui/match/match-pattern-field-mismatch-2.stderr | 12 +++ tests/ui/match/match-pattern-field-mismatch.rs | 16 +++ tests/ui/match/match-pattern-field-mismatch.stderr | 21 ++++ tests/ui/match/match-range-fail-2.rs | 24 +++++ tests/ui/match/match-range-fail-2.stderr | 40 +++++++ tests/ui/match/match-range-fail.rs | 22 ++++ tests/ui/match/match-range-fail.stderr | 40 +++++++ tests/ui/match/match-ref-mut-invariance.rs | 15 +++ tests/ui/match/match-ref-mut-invariance.stderr | 17 +++ tests/ui/match/match-ref-mut-let-invariance.rs | 16 +++ tests/ui/match/match-ref-mut-let-invariance.stderr | 18 ++++ tests/ui/match/match-ref-mut-stability.rs | 37 +++++++ tests/ui/match/match-struct.rs | 11 ++ tests/ui/match/match-struct.stderr | 11 ++ tests/ui/match/match-tag-nullary.rs | 4 + tests/ui/match/match-tag-nullary.stderr | 14 +++ tests/ui/match/match-tag-unary.rs | 4 + tests/ui/match/match-tag-unary.stderr | 11 ++ tests/ui/match/match-type-err-first-arm.rs | 50 +++++++++ tests/ui/match/match-type-err-first-arm.stderr | 65 ++++++++++++ tests/ui/match/match-unresolved-one-arm.rs | 7 ++ tests/ui/match/match-unresolved-one-arm.stderr | 14 +++ tests/ui/match/match-vec-mismatch-2.rs | 6 ++ tests/ui/match/match-vec-mismatch-2.stderr | 9 ++ tests/ui/match/match-wildcards.rs | 21 ++++ tests/ui/match/match_non_exhaustive.rs | 32 ++++++ tests/ui/match/match_non_exhaustive.stderr | 56 ++++++++++ tests/ui/match/pattern-deref-miscompile.rs | 46 +++++++++ tests/ui/match/single-line.rs | 3 + tests/ui/match/single-line.stderr | 12 +++ 85 files changed, 1848 insertions(+) create mode 100644 tests/ui/match/auxiliary/match_non_exhaustive_lib.rs create mode 100644 tests/ui/match/const_non_normal_zst_ref_pattern.rs create mode 100644 tests/ui/match/expr-match-panic-fn.rs create mode 100644 tests/ui/match/expr-match-panic.rs create mode 100644 tests/ui/match/expr_before_ident_pat.rs create mode 100644 tests/ui/match/expr_before_ident_pat.stderr create mode 100644 tests/ui/match/guards.rs create mode 100644 tests/ui/match/issue-11319.rs create mode 100644 tests/ui/match/issue-11319.stderr create mode 100644 tests/ui/match/issue-11940.rs create mode 100644 tests/ui/match/issue-12552.rs create mode 100644 tests/ui/match/issue-12552.stderr create mode 100644 tests/ui/match/issue-18060.rs create mode 100644 tests/ui/match/issue-26251.rs create mode 100644 tests/ui/match/issue-26996.rs create mode 100644 tests/ui/match/issue-27021.rs create mode 100644 tests/ui/match/issue-33498.rs create mode 100644 tests/ui/match/issue-41255.rs create mode 100644 tests/ui/match/issue-41255.stderr create mode 100644 tests/ui/match/issue-42679.rs create mode 100644 tests/ui/match/issue-46920-byte-array-patterns.rs create mode 100644 tests/ui/match/issue-5530.rs create mode 100644 tests/ui/match/issue-56685.rs create mode 100644 tests/ui/match/issue-56685.stderr create mode 100644 tests/ui/match/issue-70972-dyn-trait.rs create mode 100644 tests/ui/match/issue-70972-dyn-trait.stderr create mode 100644 tests/ui/match/issue-72680.rs create mode 100644 tests/ui/match/issue-72896.rs create mode 100644 tests/ui/match/issue-74050-end-span.rs create mode 100644 tests/ui/match/issue-74050-end-span.stderr create mode 100644 tests/ui/match/issue-82392.rs create mode 100644 tests/ui/match/issue-82392.stdout create mode 100644 tests/ui/match/issue-82866.rs create mode 100644 tests/ui/match/issue-82866.stderr create mode 100644 tests/ui/match/issue-84434.rs create mode 100644 tests/ui/match/issue-91058.rs create mode 100644 tests/ui/match/issue-91058.stderr create mode 100644 tests/ui/match/issue-92100.rs create mode 100644 tests/ui/match/issue-92100.stderr create mode 100644 tests/ui/match/match-arm-resolving-to-never.rs create mode 100644 tests/ui/match/match-arm-resolving-to-never.stderr create mode 100644 tests/ui/match/match-bot-panic.rs create mode 100644 tests/ui/match/match-disc-bot.rs create mode 100644 tests/ui/match/match-fn-call.rs create mode 100644 tests/ui/match/match-fn-call.stderr create mode 100644 tests/ui/match/match-ill-type2.rs create mode 100644 tests/ui/match/match-ill-type2.stderr create mode 100644 tests/ui/match/match-incompat-type-semi.rs create mode 100644 tests/ui/match/match-incompat-type-semi.stderr create mode 100644 tests/ui/match/match-join.rs create mode 100644 tests/ui/match/match-join.stderr create mode 100644 tests/ui/match/match-no-arms-unreachable-after.rs create mode 100644 tests/ui/match/match-no-arms-unreachable-after.stderr create mode 100644 tests/ui/match/match-on-negative-integer-ranges.rs create mode 100644 tests/ui/match/match-pattern-field-mismatch-2.rs create mode 100644 tests/ui/match/match-pattern-field-mismatch-2.stderr create mode 100644 tests/ui/match/match-pattern-field-mismatch.rs create mode 100644 tests/ui/match/match-pattern-field-mismatch.stderr create mode 100644 tests/ui/match/match-range-fail-2.rs create mode 100644 tests/ui/match/match-range-fail-2.stderr create mode 100644 tests/ui/match/match-range-fail.rs create mode 100644 tests/ui/match/match-range-fail.stderr create mode 100644 tests/ui/match/match-ref-mut-invariance.rs create mode 100644 tests/ui/match/match-ref-mut-invariance.stderr create mode 100644 tests/ui/match/match-ref-mut-let-invariance.rs create mode 100644 tests/ui/match/match-ref-mut-let-invariance.stderr create mode 100644 tests/ui/match/match-ref-mut-stability.rs create mode 100644 tests/ui/match/match-struct.rs create mode 100644 tests/ui/match/match-struct.stderr create mode 100644 tests/ui/match/match-tag-nullary.rs create mode 100644 tests/ui/match/match-tag-nullary.stderr create mode 100644 tests/ui/match/match-tag-unary.rs create mode 100644 tests/ui/match/match-tag-unary.stderr create mode 100644 tests/ui/match/match-type-err-first-arm.rs create mode 100644 tests/ui/match/match-type-err-first-arm.stderr create mode 100644 tests/ui/match/match-unresolved-one-arm.rs create mode 100644 tests/ui/match/match-unresolved-one-arm.stderr create mode 100644 tests/ui/match/match-vec-mismatch-2.rs create mode 100644 tests/ui/match/match-vec-mismatch-2.stderr create mode 100644 tests/ui/match/match-wildcards.rs create mode 100644 tests/ui/match/match_non_exhaustive.rs create mode 100644 tests/ui/match/match_non_exhaustive.stderr create mode 100644 tests/ui/match/pattern-deref-miscompile.rs create mode 100644 tests/ui/match/single-line.rs create mode 100644 tests/ui/match/single-line.stderr (limited to 'tests/ui/match') diff --git a/tests/ui/match/auxiliary/match_non_exhaustive_lib.rs b/tests/ui/match/auxiliary/match_non_exhaustive_lib.rs new file mode 100644 index 000000000..3be72551e --- /dev/null +++ b/tests/ui/match/auxiliary/match_non_exhaustive_lib.rs @@ -0,0 +1,5 @@ +#[non_exhaustive] +pub enum E1 {} + +#[non_exhaustive] +pub enum E2 { A, B } diff --git a/tests/ui/match/const_non_normal_zst_ref_pattern.rs b/tests/ui/match/const_non_normal_zst_ref_pattern.rs new file mode 100644 index 000000000..a114fafb6 --- /dev/null +++ b/tests/ui/match/const_non_normal_zst_ref_pattern.rs @@ -0,0 +1,9 @@ +// check-pass + +const FOO: isize = 10; +const ZST: &() = unsafe { std::mem::transmute(FOO) }; +fn main() { + match &() { + ZST => 9, + }; +} diff --git a/tests/ui/match/expr-match-panic-fn.rs b/tests/ui/match/expr-match-panic-fn.rs new file mode 100644 index 000000000..ea471717e --- /dev/null +++ b/tests/ui/match/expr-match-panic-fn.rs @@ -0,0 +1,19 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn f() -> ! { + panic!() +} + +fn g() -> isize { + let x = match true { + true => f(), + false => 10, + }; + return x; +} + +fn main() { + g(); +} diff --git a/tests/ui/match/expr-match-panic.rs b/tests/ui/match/expr-match-panic.rs new file mode 100644 index 000000000..53f8a8bd3 --- /dev/null +++ b/tests/ui/match/expr-match-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn main() { + let _x = match true { + false => 0, + true => panic!(), + }; +} diff --git a/tests/ui/match/expr_before_ident_pat.rs b/tests/ui/match/expr_before_ident_pat.rs new file mode 100644 index 000000000..27ef3d05a --- /dev/null +++ b/tests/ui/match/expr_before_ident_pat.rs @@ -0,0 +1,13 @@ +macro_rules! funny { + ($a:expr, $b:ident) => { + match [1, 2] { + [$a, $b] => {} + } + }; +} + +fn main() { + funny!(a, a); + //~^ ERROR cannot find value `a` in this scope + //~| ERROR arbitrary expressions aren't allowed in patterns +} diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr new file mode 100644 index 000000000..57a2d2b26 --- /dev/null +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/expr_before_ident_pat.rs:10:12 + | +LL | funny!(a, a); + | ^ not found in this scope + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/expr_before_ident_pat.rs:10:12 + | +LL | funny!(a, a); + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/match/guards.rs b/tests/ui/match/guards.rs new file mode 100644 index 000000000..10a4bb673 --- /dev/null +++ b/tests/ui/match/guards.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(non_shorthand_field_patterns)] + +#[derive(Copy, Clone)] +struct Pair { x: isize, y: isize } + +pub fn main() { + let a: isize = + match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } }; + assert_eq!(a, 2); + + let b: isize = + match (Pair {x: 10, y: 20}) { + x if x.x < 5 && x.y < 5 => { 1 } + Pair {x: x, y: y} if x == 10 && y == 20 => { 2 } + Pair {x: _x, y: _y} => { 3 } + }; + assert_eq!(b, 2); +} diff --git a/tests/ui/match/issue-11319.rs b/tests/ui/match/issue-11319.rs new file mode 100644 index 000000000..ab69ab250 --- /dev/null +++ b/tests/ui/match/issue-11319.rs @@ -0,0 +1,13 @@ +fn main() { + match Some(10) { + //~^ NOTE `match` arms have incompatible types + Some(5) => false, + //~^ NOTE this is found to be of type `bool` + Some(2) => true, + //~^ NOTE this is found to be of type `bool` + None => (), + //~^ ERROR `match` arms have incompatible types + //~| NOTE expected `bool`, found `()` + _ => true + } +} diff --git a/tests/ui/match/issue-11319.stderr b/tests/ui/match/issue-11319.stderr new file mode 100644 index 000000000..fc44205e8 --- /dev/null +++ b/tests/ui/match/issue-11319.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/issue-11319.rs:8:20 + | +LL | / match Some(10) { +LL | | +LL | | Some(5) => false, + | | ----- this is found to be of type `bool` +LL | | +LL | | Some(2) => true, + | | ---- this is found to be of type `bool` +LL | | +LL | | None => (), + | | ^^ expected `bool`, found `()` +... | +LL | | _ => true +LL | | } + | |_____- `match` arms have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/issue-11940.rs b/tests/ui/match/issue-11940.rs new file mode 100644 index 000000000..6815c87ed --- /dev/null +++ b/tests/ui/match/issue-11940.rs @@ -0,0 +1,11 @@ +// run-pass + +const TEST_STR: &'static str = "abcd"; + +fn main() { + let s = "abcd"; + match s { + TEST_STR => (), + _ => unreachable!() + } +} diff --git a/tests/ui/match/issue-12552.rs b/tests/ui/match/issue-12552.rs new file mode 100644 index 000000000..b7f71dd1c --- /dev/null +++ b/tests/ui/match/issue-12552.rs @@ -0,0 +1,11 @@ +// this code used to cause an ICE + +fn main() { + let t = Err(0); + match t { + Some(k) => match k { //~ ERROR mismatched types + a => println!("{}", a) + }, + None => () //~ ERROR mismatched types + } +} diff --git a/tests/ui/match/issue-12552.stderr b/tests/ui/match/issue-12552.stderr new file mode 100644 index 000000000..4b027eba2 --- /dev/null +++ b/tests/ui/match/issue-12552.stderr @@ -0,0 +1,34 @@ +error[E0308]: mismatched types + --> $DIR/issue-12552.rs:6:5 + | +LL | match t { + | - this expression has type `Result<_, {integer}>` +LL | Some(k) => match k { + | ^^^^^^^ expected enum `Result`, found enum `Option` + | + = note: expected enum `Result<_, {integer}>` + found enum `Option<_>` +help: try wrapping the pattern in `Ok` + | +LL | Ok(Some(k)) => match k { + | +++ + + +error[E0308]: mismatched types + --> $DIR/issue-12552.rs:9:5 + | +LL | match t { + | - this expression has type `Result<_, {integer}>` +... +LL | None => () + | ^^^^ expected enum `Result`, found enum `Option` + | + = note: expected enum `Result<_, {integer}>` + found enum `Option<_>` +help: try wrapping the pattern in `Ok` + | +LL | Ok(None) => () + | +++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/issue-18060.rs b/tests/ui/match/issue-18060.rs new file mode 100644 index 000000000..b5f3d0f74 --- /dev/null +++ b/tests/ui/match/issue-18060.rs @@ -0,0 +1,8 @@ +// run-pass +// Regression test for #18060: match arms were matching in the wrong order. + +fn main() { + assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 }); + assert_eq!(2, match (1, 3) { (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 }); + assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 }); +} diff --git a/tests/ui/match/issue-26251.rs b/tests/ui/match/issue-26251.rs new file mode 100644 index 000000000..a3e26a412 --- /dev/null +++ b/tests/ui/match/issue-26251.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(overlapping_range_endpoints)] + +fn main() { + let x = 'a'; + + let y = match x { + 'a'..='b' if false => "one", + 'a' => "two", + 'a'..='b' => "three", + _ => panic!("what?"), + }; + + assert_eq!(y, "two"); +} diff --git a/tests/ui/match/issue-26996.rs b/tests/ui/match/issue-26996.rs new file mode 100644 index 000000000..84037b72a --- /dev/null +++ b/tests/ui/match/issue-26996.rs @@ -0,0 +1,24 @@ +// run-pass + +// This test is bogus (i.e., should be check-fail) during the period +// where #54986 is implemented and #54987 is *not* implemented. For +// now: just ignore it +// +// ignore-test + +// This test is checking that the write to `c.0` (which has been moved out of) +// won't overwrite the state in `c2`. +// +// That's a fine thing to test when this code is accepted by the +// compiler, and this code is being transcribed accordingly into +// the ui test issue-21232-partial-init-and-use.rs + +fn main() { + let mut c = (1, "".to_owned()); + match c { + c2 => { + c.0 = 2; + assert_eq!(c2.0, 1); + } + } +} diff --git a/tests/ui/match/issue-27021.rs b/tests/ui/match/issue-27021.rs new file mode 100644 index 000000000..ef3b114a5 --- /dev/null +++ b/tests/ui/match/issue-27021.rs @@ -0,0 +1,28 @@ +// run-pass + +// This test is bogus (i.e., should be check-fail) during the period +// where #54986 is implemented and #54987 is *not* implemented. For +// now: just ignore it +// +// ignore-test + +// These are variants of issue-26996.rs. In all cases we are writing +// into a record field that has been moved out of, and ensuring that +// such a write won't overwrite the state of the thing it was moved +// into. +// +// That's a fine thing to test when this code is accepted by the +// compiler, and this code is being transcribed accordingly into +// the ui test issue-21232-partial-init-and-use.rs + +fn main() { + let mut c = (1, (1, "".to_owned())); + match c { + c2 => { (c.1).0 = 2; assert_eq!((c2.1).0, 1); } + } + + let mut c = (1, (1, (1, "".to_owned()))); + match c.1 { + c2 => { ((c.1).1).0 = 3; assert_eq!((c2.1).0, 1); } + } +} diff --git a/tests/ui/match/issue-33498.rs b/tests/ui/match/issue-33498.rs new file mode 100644 index 000000000..9c8a97e7e --- /dev/null +++ b/tests/ui/match/issue-33498.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +pub fn main() { + let x = (0, 2); + + match x { + (0, ref y) => {} + (y, 0) => {} + _ => (), + } +} diff --git a/tests/ui/match/issue-41255.rs b/tests/ui/match/issue-41255.rs new file mode 100644 index 000000000..d163801fd --- /dev/null +++ b/tests/ui/match/issue-41255.rs @@ -0,0 +1,50 @@ +// Matching against float literals should result in a linter error + +#![feature(exclusive_range_pattern)] +#![allow(unused)] +#![forbid(illegal_floating_point_literal_pattern)] + +fn main() { + let x = 42.0; + match x { + 5.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + 5.0f32 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + -5.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + 1.0 .. 33.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + 39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns + //~| ERROR floating-point types cannot be used in patterns + //~| WARNING hard error + //~| WARNING hard error + + ..71.0 => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler + ..=72.0 => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler + 71.0.. => {} + //~^ ERROR floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler + _ => {}, + }; + let y = 5.0; + // Same for tuples + match (x, 5) { + (3.14, 1) => {}, //~ ERROR floating-point types cannot be used + //~| WARNING hard error + _ => {}, + } + // Or structs + struct Foo { x: f32 }; + match (Foo { x }) { + Foo { x: 2.0 } => {}, //~ ERROR floating-point types cannot be used + //~| WARNING hard error + _ => {}, + } +} diff --git a/tests/ui/match/issue-41255.stderr b/tests/ui/match/issue-41255.stderr new file mode 100644 index 000000000..9bc49654e --- /dev/null +++ b/tests/ui/match/issue-41255.stderr @@ -0,0 +1,115 @@ +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:10:9 + | +LL | 5.0 => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 +note: the lint level is defined here + --> $DIR/issue-41255.rs:5:11 + | +LL | #![forbid(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:12:9 + | +LL | 5.0f32 => {}, + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:14:10 + | +LL | -5.0 => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:16:9 + | +LL | 1.0 .. 33.0 => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:16:16 + | +LL | 1.0 .. 33.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:20:9 + | +LL | 39.0 ..= 70.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:20:18 + | +LL | 39.0 ..= 70.0 => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:25:11 + | +LL | ..71.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:28:12 + | +LL | ..=72.0 => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:31:9 + | +LL | 71.0.. => {} + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:39:10 + | +LL | (3.14, 1) => {}, + | ^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: floating-point types cannot be used in patterns + --> $DIR/issue-41255.rs:46:18 + | +LL | Foo { x: 2.0 } => {}, + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 + +error: aborting due to 12 previous errors + diff --git a/tests/ui/match/issue-42679.rs b/tests/ui/match/issue-42679.rs new file mode 100644 index 000000000..46a0bd35d --- /dev/null +++ b/tests/ui/match/issue-42679.rs @@ -0,0 +1,21 @@ +// run-pass +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum Test { + Foo(usize), + Bar(isize), +} + +fn main() { + let a = Box::new(Test::Foo(10)); + let b = Box::new(Test::Bar(-20)); + match (a, b) { + (_, box Test::Foo(_)) => unreachable!(), + (box Test::Foo(x), b) => { + assert_eq!(x, 10); + assert_eq!(b, Box::new(Test::Bar(-20))); + }, + _ => unreachable!(), + } +} diff --git a/tests/ui/match/issue-46920-byte-array-patterns.rs b/tests/ui/match/issue-46920-byte-array-patterns.rs new file mode 100644 index 000000000..2a8b4bb49 --- /dev/null +++ b/tests/ui/match/issue-46920-byte-array-patterns.rs @@ -0,0 +1,28 @@ +// run-pass +const CURSOR_PARTITION_LABEL: &'static [u8] = b"partition"; +const CURSOR_EVENT_TYPE_LABEL: &'static [u8] = b"event_type"; +const BYTE_PATTERN: &'static [u8; 5] = b"hello"; + +fn match_slice(x: &[u8]) -> u32 { + match x { + CURSOR_PARTITION_LABEL => 0, + CURSOR_EVENT_TYPE_LABEL => 1, + _ => 2, + } +} + +fn match_array(x: &[u8; 5]) -> bool { + match x { + BYTE_PATTERN => true, + _ => false + } +} + +fn main() { + assert_eq!(match_slice(b"abcde"), 2); + assert_eq!(match_slice(b"event_type"), 1); + assert_eq!(match_slice(b"partition"), 0); + + assert_eq!(match_array(b"hello"), true); + assert_eq!(match_array(b"hella"), false); +} diff --git a/tests/ui/match/issue-5530.rs b/tests/ui/match/issue-5530.rs new file mode 100644 index 000000000..72731cbb1 --- /dev/null +++ b/tests/ui/match/issue-5530.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] + +enum Enum { + Foo { foo: usize }, + Bar { bar: usize } +} + +fn fun1(e1: &Enum, e2: &Enum) -> usize { + match (e1, e2) { + (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0, + (&Enum::Foo { foo: _ }, &Enum::Bar { bar: _ }) => 1, + (&Enum::Bar { bar: _ }, &Enum::Bar { bar: _ }) => 2, + (&Enum::Bar { bar: _ }, &Enum::Foo { foo: _ }) => 3, + } +} + +fn fun2(e1: &Enum, e2: &Enum) -> usize { + match (e1, e2) { + (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0, + (&Enum::Foo { foo: _ }, _ ) => 1, + (&Enum::Bar { bar: _ }, &Enum::Bar { bar: _ }) => 2, + (&Enum::Bar { bar: _ }, _ ) => 3, + } +} + +pub fn main() { + let foo = Enum::Foo { foo: 1 }; + let bar = Enum::Bar { bar: 1 }; + + assert_eq!(fun1(&foo, &foo), 0); + assert_eq!(fun1(&foo, &bar), 1); + assert_eq!(fun1(&bar, &bar), 2); + assert_eq!(fun1(&bar, &foo), 3); + + assert_eq!(fun2(&foo, &foo), 0); + assert_eq!(fun2(&foo, &bar), 1); // fun2 returns 0 + assert_eq!(fun2(&bar, &bar), 2); + assert_eq!(fun2(&bar, &foo), 3); // fun2 returns 2 +} diff --git a/tests/ui/match/issue-56685.rs b/tests/ui/match/issue-56685.rs new file mode 100644 index 000000000..f320c99ed --- /dev/null +++ b/tests/ui/match/issue-56685.rs @@ -0,0 +1,44 @@ +#![allow(dead_code)] +#![deny(unused_variables)] + +// This test aims to check that unused variable suggestions update bindings in all +// match arms. + +fn main() { + enum E { + A(i32,), + B(i32,), + } + + match E::A(1) { + E::A(x) | E::B(x) => {} + //~^ ERROR unused variable: `x` + } + + enum F { + A(i32, i32,), + B(i32, i32,), + C(i32, i32,), + } + + let _ = match F::A(1, 2) { + F::A(x, y) | F::B(x, y) => { y }, + //~^ ERROR unused variable: `x` + F::C(a, b) => { 3 } + //~^ ERROR unused variable: `a` + //~^^ ERROR unused variable: `b` + }; + + let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + //~^ ERROR unused variable: `x` + y + } else { + 3 + }; + + while let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + //~^ ERROR unused variable: `x` + let _ = y; + break; + } +} diff --git a/tests/ui/match/issue-56685.stderr b/tests/ui/match/issue-56685.stderr new file mode 100644 index 000000000..ccf357d4a --- /dev/null +++ b/tests/ui/match/issue-56685.stderr @@ -0,0 +1,63 @@ +error: unused variable: `x` + --> $DIR/issue-56685.rs:14:14 + | +LL | E::A(x) | E::B(x) => {} + | ^ ^ + | +note: the lint level is defined here + --> $DIR/issue-56685.rs:2:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ +help: if this is intentional, prefix it with an underscore + | +LL | E::A(_x) | E::B(_x) => {} + | ~~ ~~ + +error: unused variable: `x` + --> $DIR/issue-56685.rs:25:14 + | +LL | F::A(x, y) | F::B(x, y) => { y }, + | ^ ^ + | +help: if this is intentional, prefix it with an underscore + | +LL | F::A(_x, y) | F::B(_x, y) => { y }, + | ~~ ~~ + +error: unused variable: `a` + --> $DIR/issue-56685.rs:27:14 + | +LL | F::C(a, b) => { 3 } + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/issue-56685.rs:27:17 + | +LL | F::C(a, b) => { 3 } + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `x` + --> $DIR/issue-56685.rs:32:25 + | +LL | let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + | ^ ^ + | +help: if this is intentional, prefix it with an underscore + | +LL | let _ = if let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) { + | ~~ ~~ + +error: unused variable: `x` + --> $DIR/issue-56685.rs:39:20 + | +LL | while let F::A(x, y) | F::B(x, y) = F::A(1, 2) { + | ^ ^ + | +help: if this is intentional, prefix it with an underscore + | +LL | while let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) { + | ~~ ~~ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/match/issue-70972-dyn-trait.rs b/tests/ui/match/issue-70972-dyn-trait.rs new file mode 100644 index 000000000..97d161c59 --- /dev/null +++ b/tests/ui/match/issue-70972-dyn-trait.rs @@ -0,0 +1,10 @@ +const F: &'static dyn Send = &7u32; + +fn main() { + let a: &dyn Send = &7u32; + match a { + F => panic!(), + //~^ ERROR `&dyn Send` cannot be used in patterns + _ => {} + } +} diff --git a/tests/ui/match/issue-70972-dyn-trait.stderr b/tests/ui/match/issue-70972-dyn-trait.stderr new file mode 100644 index 000000000..7581070eb --- /dev/null +++ b/tests/ui/match/issue-70972-dyn-trait.stderr @@ -0,0 +1,8 @@ +error: `&dyn Send` cannot be used in patterns + --> $DIR/issue-70972-dyn-trait.rs:6:9 + | +LL | F => panic!(), + | ^ + +error: aborting due to previous error + diff --git a/tests/ui/match/issue-72680.rs b/tests/ui/match/issue-72680.rs new file mode 100644 index 000000000..c13cace76 --- /dev/null +++ b/tests/ui/match/issue-72680.rs @@ -0,0 +1,63 @@ +// run-pass + +fn main() { + assert!(f("", 0)); + assert!(f("a", 1)); + assert!(f("b", 1)); + + assert!(!f("", 1)); + assert!(!f("a", 0)); + assert!(!f("b", 0)); + + assert!(!f("asdf", 32)); + + //// + + assert!(!g(true, true, true)); + assert!(!g(false, true, true)); + assert!(!g(true, false, true)); + assert!(!g(false, false, true)); + assert!(!g(true, true, false)); + + assert!(g(false, true, false)); + assert!(g(true, false, false)); + assert!(g(false, false, false)); + + //// + + assert!(!h(true, true, true)); + assert!(!h(false, true, true)); + assert!(!h(true, false, true)); + assert!(!h(false, false, true)); + assert!(!h(true, true, false)); + + assert!(h(false, true, false)); + assert!(h(true, false, false)); + assert!(h(false, false, false)); +} + +fn f(s: &str, num: usize) -> bool { + match (s, num) { + ("", 0) | ("a" | "b", 1) => true, + + _ => false, + } +} + +fn g(x: bool, y: bool, z: bool) -> bool { + match (x, y, x, z) { + (true | false, false, true, false) => true, + (false, true | false, true | false, false) => true, + (true | false, true | false, true | false, true) => false, + (true, true | false, true | false, false) => false, + } +} + +fn h(x: bool, y: bool, z: bool) -> bool { + match (x, (y, (x, (z,)))) { + (true | false, (false, (true, (false,)))) => true, + (false, (true | false, (true | false, (false,)))) => true, + (true | false, (true | false, (true | false, (true,)))) => false, + (true, (true | false, (true | false, (false,)))) => false, + } +} diff --git a/tests/ui/match/issue-72896.rs b/tests/ui/match/issue-72896.rs new file mode 100644 index 000000000..3a8b82037 --- /dev/null +++ b/tests/ui/match/issue-72896.rs @@ -0,0 +1,23 @@ +// run-pass +trait EnumSetType { + type Repr; +} + +enum Enum8 { } +impl EnumSetType for Enum8 { + type Repr = u8; +} + +#[derive(PartialEq, Eq)] +struct EnumSet { + __enumset_underlying: T::Repr, +} + +const CONST_SET: EnumSet = EnumSet { __enumset_underlying: 3 }; + +fn main() { + match CONST_SET { + CONST_SET => { /* ok */ } + _ => panic!("match fell through?"), + } +} diff --git a/tests/ui/match/issue-74050-end-span.rs b/tests/ui/match/issue-74050-end-span.rs new file mode 100644 index 000000000..cc81214e2 --- /dev/null +++ b/tests/ui/match/issue-74050-end-span.rs @@ -0,0 +1,13 @@ +fn main() { + let mut args = std::env::args_os(); + let _arg = match args.next() { + Some(arg) => { + match arg.to_str() { + //~^ ERROR `arg` does not live long enough + Some(s) => s, + None => return, + } + } + None => return, + }; +} diff --git a/tests/ui/match/issue-74050-end-span.stderr b/tests/ui/match/issue-74050-end-span.stderr new file mode 100644 index 000000000..59c091e44 --- /dev/null +++ b/tests/ui/match/issue-74050-end-span.stderr @@ -0,0 +1,15 @@ +error[E0597]: `arg` does not live long enough + --> $DIR/issue-74050-end-span.rs:5:19 + | +LL | let _arg = match args.next() { + | ---- borrow later stored here +LL | Some(arg) => { +LL | match arg.to_str() { + | ^^^^^^^^^^^^ borrowed value does not live long enough +... +LL | } + | - `arg` dropped here while still borrowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/match/issue-82392.rs b/tests/ui/match/issue-82392.rs new file mode 100644 index 000000000..d26d88304 --- /dev/null +++ b/tests/ui/match/issue-82392.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/82329 +// compile-flags: -Zunpretty=hir,typed +// check-pass + +pub fn main() { + if true { + } else if let Some(a) = Some(3) { + } +} diff --git a/tests/ui/match/issue-82392.stdout b/tests/ui/match/issue-82392.stdout new file mode 100644 index 000000000..ffe730743 --- /dev/null +++ b/tests/ui/match/issue-82392.stdout @@ -0,0 +1,16 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +// https://github.com/rust-lang/rust/issues/82329 +// compile-flags: -Zunpretty=hir,typed +// check-pass + +fn main() ({ + (if (true as bool) + ({ } as + ()) else if (let Some(a) = + ((Some as + fn(i32) -> Option {Option::::Some})((3 as i32)) as + Option) as bool) ({ } as ()) as ()) + } as ()) diff --git a/tests/ui/match/issue-82866.rs b/tests/ui/match/issue-82866.rs new file mode 100644 index 000000000..95cd62261 --- /dev/null +++ b/tests/ui/match/issue-82866.rs @@ -0,0 +1,7 @@ +fn main() { + match x { + //~^ ERROR cannot find value `x` in this scope + Some::(v) => (), + //~^ ERROR cannot find type `v` in this scope + } +} diff --git a/tests/ui/match/issue-82866.stderr b/tests/ui/match/issue-82866.stderr new file mode 100644 index 000000000..f9e3360a5 --- /dev/null +++ b/tests/ui/match/issue-82866.stderr @@ -0,0 +1,16 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/issue-82866.rs:2:11 + | +LL | match x { + | ^ not found in this scope + +error[E0412]: cannot find type `v` in this scope + --> $DIR/issue-82866.rs:4:16 + | +LL | Some::(v) => (), + | ^ not found in this scope + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/match/issue-84434.rs b/tests/ui/match/issue-84434.rs new file mode 100644 index 000000000..423481fd5 --- /dev/null +++ b/tests/ui/match/issue-84434.rs @@ -0,0 +1,18 @@ +// https://github.com/rust-lang/rust/issues/84434 +// check-pass + +use std::path::Path; +struct A { + pub func: fn(check: bool, a: &Path, b: Option<&Path>), +} +const MY_A: A = A { + func: |check, a, b| { + if check { + let _ = (); + } else if let Some(parent) = b.and_then(|p| p.parent()) { + let _ = (); + } + }, +}; + +fn main() {} diff --git a/tests/ui/match/issue-91058.rs b/tests/ui/match/issue-91058.rs new file mode 100644 index 000000000..4845937d5 --- /dev/null +++ b/tests/ui/match/issue-91058.rs @@ -0,0 +1,11 @@ +struct S(()); + +fn main() { + let array = [S(())]; + + match array { + [()] => {} + //~^ ERROR mismatched types [E0308] + _ => {} + } +} diff --git a/tests/ui/match/issue-91058.stderr b/tests/ui/match/issue-91058.stderr new file mode 100644 index 000000000..ec1d7e21f --- /dev/null +++ b/tests/ui/match/issue-91058.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/issue-91058.rs:7:10 + | +LL | match array { + | ----- this expression has type `[S; 1]` +LL | [()] => {} + | ^^ expected struct `S`, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/issue-92100.rs b/tests/ui/match/issue-92100.rs new file mode 100644 index 000000000..baac570dd --- /dev/null +++ b/tests/ui/match/issue-92100.rs @@ -0,0 +1,7 @@ +#![feature(half_open_range_patterns_in_slices)] + +fn main() { + match [1, 2] { + [a.., a] => {} //~ ERROR cannot find value `a` in this scope + } +} diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr new file mode 100644 index 000000000..0f694c587 --- /dev/null +++ b/tests/ui/match/issue-92100.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/issue-92100.rs:5:10 + | +LL | [a.., a] => {} + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/match/match-arm-resolving-to-never.rs b/tests/ui/match/match-arm-resolving-to-never.rs new file mode 100644 index 000000000..6ef249c05 --- /dev/null +++ b/tests/ui/match/match-arm-resolving-to-never.rs @@ -0,0 +1,19 @@ +enum E { + A, + B, + C, + D, + E, + F, +} + +fn main() { + match E::F { + E::A => 1, + E::B => 2, + E::C => 3, + E::D => 4, + E::E => unimplemented!(""), + E::F => "", //~ ERROR `match` arms have incompatible types + }; +} diff --git a/tests/ui/match/match-arm-resolving-to-never.stderr b/tests/ui/match/match-arm-resolving-to-never.stderr new file mode 100644 index 000000000..686fbd0ba --- /dev/null +++ b/tests/ui/match/match-arm-resolving-to-never.stderr @@ -0,0 +1,18 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/match-arm-resolving-to-never.rs:17:17 + | +LL | / match E::F { +LL | | E::A => 1, +LL | | E::B => 2, +LL | | E::C => 3, +LL | | E::D => 4, +LL | | E::E => unimplemented!(""), + | | ------------------ this and all prior arms are found to be of type `{integer}` +LL | | E::F => "", + | | ^^ expected integer, found `&str` +LL | | }; + | |_____- `match` arms have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-bot-panic.rs b/tests/ui/match/match-bot-panic.rs new file mode 100644 index 000000000..e4a6f6d6f --- /dev/null +++ b/tests/ui/match/match-bot-panic.rs @@ -0,0 +1,16 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +#![allow(unreachable_code)] +#![allow(unused_variables)] + +fn foo(s: String) {} + +fn main() { + let i = match Some::(3) { + None:: => panic!(), + Some::(_) => panic!(), + }; + foo(i); +} diff --git a/tests/ui/match/match-disc-bot.rs b/tests/ui/match/match-disc-bot.rs new file mode 100644 index 000000000..18cfd5e23 --- /dev/null +++ b/tests/ui/match/match-disc-bot.rs @@ -0,0 +1,16 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn f() -> ! { + panic!("quux") +} +fn g() -> isize { + match f() { + true => 1, + false => 0, + } +} +fn main() { + g(); +} diff --git a/tests/ui/match/match-fn-call.rs b/tests/ui/match/match-fn-call.rs new file mode 100644 index 000000000..99092602c --- /dev/null +++ b/tests/ui/match/match-fn-call.rs @@ -0,0 +1,12 @@ +use std::path::Path; + +fn main() { + let path = Path::new("foo"); + match path { + Path::new("foo") => println!("foo"), + //~^ ERROR expected tuple struct or tuple variant + Path::new("bar") => println!("bar"), + //~^ ERROR expected tuple struct or tuple variant + _ => (), + } +} diff --git a/tests/ui/match/match-fn-call.stderr b/tests/ui/match/match-fn-call.stderr new file mode 100644 index 000000000..297aa4cd9 --- /dev/null +++ b/tests/ui/match/match-fn-call.stderr @@ -0,0 +1,19 @@ +error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new` + --> $DIR/match-fn-call.rs:6:9 + | +LL | Path::new("foo") => println!("foo"), + | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns + | + = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + +error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new` + --> $DIR/match-fn-call.rs:8:9 + | +LL | Path::new("bar") => println!("bar"), + | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns + | + = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0164`. diff --git a/tests/ui/match/match-ill-type2.rs b/tests/ui/match/match-ill-type2.rs new file mode 100644 index 000000000..6612f6e39 --- /dev/null +++ b/tests/ui/match/match-ill-type2.rs @@ -0,0 +1,7 @@ +fn main() { + match 1i32 { + 1i32 => 1, + 2u32 => 1, //~ ERROR mismatched types + _ => 2, + }; +} diff --git a/tests/ui/match/match-ill-type2.stderr b/tests/ui/match/match-ill-type2.stderr new file mode 100644 index 000000000..5078f03d6 --- /dev/null +++ b/tests/ui/match/match-ill-type2.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/match-ill-type2.rs:4:9 + | +LL | match 1i32 { + | ---- this expression has type `i32` +LL | 1i32 => 1, +LL | 2u32 => 1, + | ^^^^ expected `i32`, found `u32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-incompat-type-semi.rs b/tests/ui/match/match-incompat-type-semi.rs new file mode 100644 index 000000000..37f6beabd --- /dev/null +++ b/tests/ui/match/match-incompat-type-semi.rs @@ -0,0 +1,52 @@ +// Diagnostic enhancement explained in issue #75418. +// Point at the last statement in the block if there's no tail expression, +// and suggest removing the semicolon if appropriate. + +fn main() { + let _ = match Some(42) { + Some(x) => { + x + }, + None => { + 0; + //~^ ERROR incompatible types + //~| HELP consider removing this semicolon + }, + }; + + let _ = if let Some(x) = Some(42) { + x + } else { + 0; + //~^ ERROR incompatible types + //~| HELP consider removing this semicolon + }; + + let _ = match Some(42) { + Some(x) => { + x + }, + None => { + (); + //~^ ERROR incompatible types + }, + }; + + let _ = match Some(42) { + Some(x) => { + x + }, + None => { //~ ERROR incompatible types + }, + }; + + let _ = match Some(42) { + Some(x) => "rust-lang.org" + .chars() + .skip(1) + .chain(Some(x as u8 as char)) + .take(10) + .any(char::is_alphanumeric), + None => {} //~ ERROR incompatible types + }; +} diff --git a/tests/ui/match/match-incompat-type-semi.stderr b/tests/ui/match/match-incompat-type-semi.stderr new file mode 100644 index 000000000..008b1c1e9 --- /dev/null +++ b/tests/ui/match/match-incompat-type-semi.stderr @@ -0,0 +1,88 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/match-incompat-type-semi.rs:11:13 + | +LL | let _ = match Some(42) { + | _____________- +LL | | Some(x) => { +LL | | x + | | - this is found to be of type `{integer}` +LL | | }, +LL | | None => { +LL | | 0; + | | ^- + | | || + | | |help: consider removing this semicolon + | | expected integer, found `()` +... | +LL | | }, +LL | | }; + | |_____- `match` arms have incompatible types + +error[E0308]: `if` and `else` have incompatible types + --> $DIR/match-incompat-type-semi.rs:20:9 + | +LL | let _ = if let Some(x) = Some(42) { + | _____________- +LL | | x + | | - expected because of this +LL | | } else { +LL | | 0; + | | ^- + | | || + | | |help: consider removing this semicolon + | | expected integer, found `()` +LL | | +LL | | +LL | | }; + | |_____- `if` and `else` have incompatible types + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-incompat-type-semi.rs:30:13 + | +LL | let _ = match Some(42) { + | _____________- +LL | | Some(x) => { +LL | | x + | | - this is found to be of type `{integer}` +LL | | }, +LL | | None => { +LL | | (); + | | ^^^ expected integer, found `()` +LL | | +LL | | }, +LL | | }; + | |_____- `match` arms have incompatible types + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-incompat-type-semi.rs:39:17 + | +LL | let _ = match Some(42) { + | -------------- `match` arms have incompatible types +LL | Some(x) => { +LL | x + | - this is found to be of type `{integer}` +LL | }, +LL | None => { + | _________________^ +LL | | }, + | |_________^ expected integer, found `()` + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-incompat-type-semi.rs:50:17 + | +LL | let _ = match Some(42) { + | -------------- `match` arms have incompatible types +LL | Some(x) => "rust-lang.org" + | ____________________- +LL | | .chars() +LL | | .skip(1) +LL | | .chain(Some(x as u8 as char)) +LL | | .take(10) +LL | | .any(char::is_alphanumeric), + | |_______________________________________- this is found to be of type `bool` +LL | None => {} + | ^^ expected `bool`, found `()` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-join.rs b/tests/ui/match/match-join.rs new file mode 100644 index 000000000..b0f2593c8 --- /dev/null +++ b/tests/ui/match/match-join.rs @@ -0,0 +1,11 @@ +// a good test that we merge paths correctly in the presence of a +// variable that's used before it's declared + +fn my_panic() -> ! { panic!(); } + +fn main() { + match true { false => { my_panic(); } true => { } } + + println!("{}", x); //~ ERROR cannot find value `x` in this scope + let x: isize; +} diff --git a/tests/ui/match/match-join.stderr b/tests/ui/match/match-join.stderr new file mode 100644 index 000000000..27a82c124 --- /dev/null +++ b/tests/ui/match/match-join.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `x` in this scope + --> $DIR/match-join.rs:9:20 + | +LL | println!("{}", x); + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/match/match-no-arms-unreachable-after.rs b/tests/ui/match/match-no-arms-unreachable-after.rs new file mode 100644 index 000000000..8f83fd1a3 --- /dev/null +++ b/tests/ui/match/match-no-arms-unreachable-after.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] +#![deny(unreachable_code)] + +enum Void { } + +fn foo(v: Void) { + match v { } + let x = 2; //~ ERROR unreachable +} + +fn main() { +} diff --git a/tests/ui/match/match-no-arms-unreachable-after.stderr b/tests/ui/match/match-no-arms-unreachable-after.stderr new file mode 100644 index 000000000..a0a369726 --- /dev/null +++ b/tests/ui/match/match-no-arms-unreachable-after.stderr @@ -0,0 +1,16 @@ +error: unreachable statement + --> $DIR/match-no-arms-unreachable-after.rs:8:5 + | +LL | match v { } + | ----------- any code following this expression is unreachable +LL | let x = 2; + | ^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/match-no-arms-unreachable-after.rs:2:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/match/match-on-negative-integer-ranges.rs b/tests/ui/match/match-on-negative-integer-ranges.rs new file mode 100644 index 000000000..53e9ea9a5 --- /dev/null +++ b/tests/ui/match/match-on-negative-integer-ranges.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + assert_eq!(false, match -50_i8 { -128i8..=-101i8 => true, _ => false, }); + + assert_eq!(false, if let -128i8..=-101i8 = -50_i8 { true } else { false }); +} diff --git a/tests/ui/match/match-pattern-field-mismatch-2.rs b/tests/ui/match/match-pattern-field-mismatch-2.rs new file mode 100644 index 000000000..fa03cdac2 --- /dev/null +++ b/tests/ui/match/match-pattern-field-mismatch-2.rs @@ -0,0 +1,16 @@ +fn main() { + enum Color { + Rgb(usize, usize, usize), + Cmyk(usize, usize, usize, usize), + NoColor, + } + + fn foo(c: Color) { + match c { + Color::Rgb(_, _, _) => { } + Color::Cmyk(_, _, _, _) => { } + Color::NoColor(_) => { } + //~^ ERROR expected tuple struct or tuple variant, found unit variant `Color::NoColor` + } + } +} diff --git a/tests/ui/match/match-pattern-field-mismatch-2.stderr b/tests/ui/match/match-pattern-field-mismatch-2.stderr new file mode 100644 index 000000000..ba32d0e99 --- /dev/null +++ b/tests/ui/match/match-pattern-field-mismatch-2.stderr @@ -0,0 +1,12 @@ +error[E0532]: expected tuple struct or tuple variant, found unit variant `Color::NoColor` + --> $DIR/match-pattern-field-mismatch-2.rs:12:11 + | +LL | NoColor, + | ------- `Color::NoColor` defined here +... +LL | Color::NoColor(_) => { } + | ^^^^^^^^^^^^^^^^^ help: use this syntax instead: `Color::NoColor` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0532`. diff --git a/tests/ui/match/match-pattern-field-mismatch.rs b/tests/ui/match/match-pattern-field-mismatch.rs new file mode 100644 index 000000000..a4fa97fef --- /dev/null +++ b/tests/ui/match/match-pattern-field-mismatch.rs @@ -0,0 +1,16 @@ +fn main() { + enum Color { + Rgb(usize, usize, usize), + Cmyk(usize, usize, usize, usize), + NoColor, + } + + fn foo(c: Color) { + match c { + Color::Rgb(_, _) => { } + //~^ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 + Color::Cmyk(_, _, _, _) => { } + Color::NoColor => { } + } + } +} diff --git a/tests/ui/match/match-pattern-field-mismatch.stderr b/tests/ui/match/match-pattern-field-mismatch.stderr new file mode 100644 index 000000000..c994ee4f6 --- /dev/null +++ b/tests/ui/match/match-pattern-field-mismatch.stderr @@ -0,0 +1,21 @@ +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields + --> $DIR/match-pattern-field-mismatch.rs:10:22 + | +LL | Rgb(usize, usize, usize), + | ----- ----- ----- tuple variant has 3 fields +... +LL | Color::Rgb(_, _) => { } + | ^ ^ expected 3 fields, found 2 + | +help: use `_` to explicitly ignore each field + | +LL | Color::Rgb(_, _, _) => { } + | +++ +help: use `..` to ignore all fields + | +LL | Color::Rgb(..) => { } + | ~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0023`. diff --git a/tests/ui/match/match-range-fail-2.rs b/tests/ui/match/match-range-fail-2.rs new file mode 100644 index 000000000..792664e1d --- /dev/null +++ b/tests/ui/match/match-range-fail-2.rs @@ -0,0 +1,24 @@ +#![feature(exclusive_range_pattern)] + +fn main() { + match 5 { + 6 ..= 1 => { } + _ => { } + }; + //~^^^ ERROR lower range bound must be less than or equal to upper + //~| ERROR lower range bound must be less than or equal to upper + + match 5 { + 0 .. 0 => { } + _ => { } + }; + //~^^^ ERROR lower range bound must be less than upper + //~| ERROR lower range bound must be less than upper + + match 5u64 { + 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } + _ => { } + }; + //~^^^ ERROR lower range bound must be less than or equal to upper + //~| ERROR lower range bound must be less than or equal to upper +} diff --git a/tests/ui/match/match-range-fail-2.stderr b/tests/ui/match/match-range-fail-2.stderr new file mode 100644 index 000000000..7a0852d7e --- /dev/null +++ b/tests/ui/match/match-range-fail-2.stderr @@ -0,0 +1,40 @@ +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:5:9 + | +LL | 6 ..= 1 => { } + | ^ lower bound larger than upper bound + +error[E0579]: lower range bound must be less than upper + --> $DIR/match-range-fail-2.rs:12:9 + | +LL | 0 .. 0 => { } + | ^ + +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:19:9 + | +LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } + | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound + +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:5:9 + | +LL | 6 ..= 1 => { } + | ^ lower bound larger than upper bound + +error[E0579]: lower range bound must be less than upper + --> $DIR/match-range-fail-2.rs:12:9 + | +LL | 0 .. 0 => { } + | ^ + +error[E0030]: lower range bound must be less than or equal to upper + --> $DIR/match-range-fail-2.rs:19:9 + | +LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } + | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0030, E0579. +For more information about an error, try `rustc --explain E0030`. diff --git a/tests/ui/match/match-range-fail.rs b/tests/ui/match/match-range-fail.rs new file mode 100644 index 000000000..e53c8463e --- /dev/null +++ b/tests/ui/match/match-range-fail.rs @@ -0,0 +1,22 @@ +fn main() { + match "wow" { + "bar" ..= "foo" => { } + }; + //~^^ ERROR only `char` and numeric types are allowed in range + + match "wow" { + 10 ..= "what" => () + }; + //~^^ ERROR only `char` and numeric types are allowed in range + + match "wow" { + true ..= "what" => {} + }; + //~^^ ERROR only `char` and numeric types are allowed in range + + match 5 { + 'c' ..= 100 => { } + _ => { } + }; + //~^^^ ERROR mismatched types +} diff --git a/tests/ui/match/match-range-fail.stderr b/tests/ui/match/match-range-fail.stderr new file mode 100644 index 000000000..65db92df1 --- /dev/null +++ b/tests/ui/match/match-range-fail.stderr @@ -0,0 +1,40 @@ +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/match-range-fail.rs:3:9 + | +LL | "bar" ..= "foo" => { } + | -----^^^^^----- + | | | + | | this is of type `&'static str` but it should be `char` or numeric + | this is of type `&'static str` but it should be `char` or numeric + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/match-range-fail.rs:8:16 + | +LL | 10 ..= "what" => () + | -- ^^^^^^ this is of type `&'static str` but it should be `char` or numeric + | | + | this is of type `{integer}` + +error[E0029]: only `char` and numeric types are allowed in range patterns + --> $DIR/match-range-fail.rs:13:9 + | +LL | true ..= "what" => {} + | ----^^^^^------ + | | | + | | this is of type `&'static str` but it should be `char` or numeric + | this is of type `bool` but it should be `char` or numeric + +error[E0308]: mismatched types + --> $DIR/match-range-fail.rs:18:9 + | +LL | match 5 { + | - this expression has type `{integer}` +LL | 'c' ..= 100 => { } + | ^^^ --- this is of type `{integer}` + | | + | expected integer, found `char` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0029, E0308. +For more information about an error, try `rustc --explain E0029`. diff --git a/tests/ui/match/match-ref-mut-invariance.rs b/tests/ui/match/match-ref-mut-invariance.rs new file mode 100644 index 000000000..4250696c6 --- /dev/null +++ b/tests/ui/match/match-ref-mut-invariance.rs @@ -0,0 +1,15 @@ +// Check that when making a ref mut binding with type `&mut T`, the +// type `T` must match precisely the type `U` of the value being +// matched, and in particular cannot be some supertype of `U`. Issue +// #23116. This test focuses on a `match`. + +#![allow(dead_code)] +struct S<'b>(&'b i32); +impl<'b> S<'b> { + fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + match self.0 { ref mut x => x } + //~^ ERROR lifetime may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/match/match-ref-mut-invariance.stderr b/tests/ui/match/match-ref-mut-invariance.stderr new file mode 100644 index 000000000..3b7e53cd5 --- /dev/null +++ b/tests/ui/match/match-ref-mut-invariance.stderr @@ -0,0 +1,17 @@ +error: lifetime may not live long enough + --> $DIR/match-ref-mut-invariance.rs:10:9 + | +LL | impl<'b> S<'b> { + | -- lifetime `'b` defined here +LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + | -- lifetime `'a` defined here +LL | match self.0 { ref mut x => x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable reference to `&i32` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance + +error: aborting due to previous error + diff --git a/tests/ui/match/match-ref-mut-let-invariance.rs b/tests/ui/match/match-ref-mut-let-invariance.rs new file mode 100644 index 000000000..a33be09ac --- /dev/null +++ b/tests/ui/match/match-ref-mut-let-invariance.rs @@ -0,0 +1,16 @@ +// Check that when making a ref mut binding with type `&mut T`, the +// type `T` must match precisely the type `U` of the value being +// matched, and in particular cannot be some supertype of `U`. Issue +// #23116. This test focuses on a `let`. + +#![allow(dead_code)] +struct S<'b>(&'b i32); +impl<'b> S<'b> { + fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + let ref mut x = self.0; + x + //~^ ERROR lifetime may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/match/match-ref-mut-let-invariance.stderr b/tests/ui/match/match-ref-mut-let-invariance.stderr new file mode 100644 index 000000000..f4d1cea67 --- /dev/null +++ b/tests/ui/match/match-ref-mut-let-invariance.stderr @@ -0,0 +1,18 @@ +error: lifetime may not live long enough + --> $DIR/match-ref-mut-let-invariance.rs:11:9 + | +LL | impl<'b> S<'b> { + | -- lifetime `'b` defined here +LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + | -- lifetime `'a` defined here +LL | let ref mut x = self.0; +LL | x + | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable reference to `&i32` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance + +error: aborting due to previous error + diff --git a/tests/ui/match/match-ref-mut-stability.rs b/tests/ui/match/match-ref-mut-stability.rs new file mode 100644 index 000000000..52120360b --- /dev/null +++ b/tests/ui/match/match-ref-mut-stability.rs @@ -0,0 +1,37 @@ +// Check that `ref mut` variables don't change address between the match guard +// and the arm expression. + +// run-pass + +// Test that z always point to the same temporary. +fn referent_stability() { + let p; + match 0 { + ref mut z if { p = z as *const _; true } => assert_eq!(p, z as *const _), + _ => unreachable!(), + }; +} + +// Test that z is always effectively the same variable. +fn variable_stability() { + let p; + match 0 { + ref mut z if { p = &z as *const _; true } => assert_eq!(p, &z as *const _), + _ => unreachable!(), + }; +} + +// Test that a borrow of *z can cross from the guard to the arm. +fn persist_borrow() { + let r; + match 0 { + ref mut z if { r = z as &_; true } => assert_eq!(*r, 0), + _ => unreachable!(), + } +} + +fn main() { + referent_stability(); + variable_stability(); + persist_borrow(); +} diff --git a/tests/ui/match/match-struct.rs b/tests/ui/match/match-struct.rs new file mode 100644 index 000000000..7a54c54b9 --- /dev/null +++ b/tests/ui/match/match-struct.rs @@ -0,0 +1,11 @@ +struct S { a: isize } +enum E { C(isize) } + +fn main() { + match (S { a: 1 }) { + E::C(_) => (), + //~^ ERROR mismatched types + //~| expected struct `S`, found enum `E` + _ => () + } +} diff --git a/tests/ui/match/match-struct.stderr b/tests/ui/match/match-struct.stderr new file mode 100644 index 000000000..a475bd5e5 --- /dev/null +++ b/tests/ui/match/match-struct.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/match-struct.rs:6:9 + | +LL | match (S { a: 1 }) { + | ------------ this expression has type `S` +LL | E::C(_) => (), + | ^^^^^^^ expected struct `S`, found enum `E` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-tag-nullary.rs b/tests/ui/match/match-tag-nullary.rs new file mode 100644 index 000000000..bb2f59969 --- /dev/null +++ b/tests/ui/match/match-tag-nullary.rs @@ -0,0 +1,4 @@ +enum A { A } +enum B { B } + +fn main() { let x: A = A::A; match x { B::B => { } } } //~ ERROR mismatched types diff --git a/tests/ui/match/match-tag-nullary.stderr b/tests/ui/match/match-tag-nullary.stderr new file mode 100644 index 000000000..a6add31d1 --- /dev/null +++ b/tests/ui/match/match-tag-nullary.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/match-tag-nullary.rs:4:40 + | +LL | enum B { B } + | - unit variant defined here +LL | +LL | fn main() { let x: A = A::A; match x { B::B => { } } } + | - ^^^^ expected enum `A`, found enum `B` + | | + | this expression has type `A` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-tag-unary.rs b/tests/ui/match/match-tag-unary.rs new file mode 100644 index 000000000..aedceafb4 --- /dev/null +++ b/tests/ui/match/match-tag-unary.rs @@ -0,0 +1,4 @@ +enum A { A(isize) } +enum B { B(isize) } + +fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } //~ ERROR mismatched types diff --git a/tests/ui/match/match-tag-unary.stderr b/tests/ui/match/match-tag-unary.stderr new file mode 100644 index 000000000..31f77bdff --- /dev/null +++ b/tests/ui/match/match-tag-unary.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/match-tag-unary.rs:4:43 + | +LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } + | - ^^^^^^^ expected enum `A`, found enum `B` + | | + | this expression has type `A` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-type-err-first-arm.rs b/tests/ui/match/match-type-err-first-arm.rs new file mode 100644 index 000000000..e9027eb24 --- /dev/null +++ b/tests/ui/match/match-type-err-first-arm.rs @@ -0,0 +1,50 @@ +fn main() { + let _ = test_func1(1); + let _ = test_func2(1); +} + +fn test_func1(n: i32) -> i32 { //~ NOTE expected `i32` because of return type + match n { + 12 => 'b', + //~^ ERROR mismatched types + //~| NOTE expected `i32`, found `char` + _ => 42, + } +} + +fn test_func2(n: i32) -> i32 { + let x = match n { //~ NOTE `match` arms have incompatible types + 12 => 'b', //~ NOTE this is found to be of type `char` + _ => 42, + //~^ ERROR `match` arms have incompatible types + //~| NOTE expected `char`, found integer + }; + x +} + +fn test_func3(n: i32) -> i32 { + let x = match n { //~ NOTE `match` arms have incompatible types + 1 => 'b', + 2 => 'b', + 3 => 'b', + 4 => 'b', + 5 => 'b', + 6 => 'b', + //~^ NOTE this and all prior arms are found to be of type `char` + _ => 42, + //~^ ERROR `match` arms have incompatible types + //~| NOTE expected `char`, found integer + }; + x +} + +fn test_func4() { + match Some(0u32) { //~ NOTE `match` arms have incompatible types + Some(x) => { + x //~ NOTE this is found to be of type `u32` + }, + None => {} + //~^ ERROR `match` arms have incompatible types + //~| NOTE expected `u32`, found `()` + }; +} diff --git a/tests/ui/match/match-type-err-first-arm.stderr b/tests/ui/match/match-type-err-first-arm.stderr new file mode 100644 index 000000000..1cfe7ce1e --- /dev/null +++ b/tests/ui/match/match-type-err-first-arm.stderr @@ -0,0 +1,65 @@ +error[E0308]: mismatched types + --> $DIR/match-type-err-first-arm.rs:8:15 + | +LL | fn test_func1(n: i32) -> i32 { + | --- expected `i32` because of return type +LL | match n { +LL | 12 => 'b', + | ^^^ expected `i32`, found `char` + | +help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes + | +LL | 12 => 'b' as i32, + | ++++++ + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-type-err-first-arm.rs:18:14 + | +LL | let x = match n { + | _____________- +LL | | 12 => 'b', + | | --- this is found to be of type `char` +LL | | _ => 42, + | | ^^ expected `char`, found integer +LL | | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-type-err-first-arm.rs:34:14 + | +LL | let x = match n { + | _____________- +LL | | 1 => 'b', +LL | | 2 => 'b', +LL | | 3 => 'b', +... | +LL | | 6 => 'b', + | | --- this and all prior arms are found to be of type `char` +LL | | +LL | | _ => 42, + | | ^^ expected `char`, found integer +LL | | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + +error[E0308]: `match` arms have incompatible types + --> $DIR/match-type-err-first-arm.rs:46:17 + | +LL | / match Some(0u32) { +LL | | Some(x) => { +LL | | x + | | - this is found to be of type `u32` +LL | | }, +LL | | None => {} + | | ^^ expected `u32`, found `()` +LL | | +LL | | +LL | | }; + | |_____- `match` arms have incompatible types + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-unresolved-one-arm.rs b/tests/ui/match/match-unresolved-one-arm.rs new file mode 100644 index 000000000..fa65d87b3 --- /dev/null +++ b/tests/ui/match/match-unresolved-one-arm.rs @@ -0,0 +1,7 @@ +fn foo() -> T { panic!("Rocks for my pillow") } + +fn main() { + let x = match () { //~ ERROR type annotations needed + () => foo() // T here should be unresolved + }; +} diff --git a/tests/ui/match/match-unresolved-one-arm.stderr b/tests/ui/match/match-unresolved-one-arm.stderr new file mode 100644 index 000000000..e3b501b2f --- /dev/null +++ b/tests/ui/match/match-unresolved-one-arm.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/match-unresolved-one-arm.rs:4:9 + | +LL | let x = match () { + | ^ + | +help: consider giving `x` an explicit type + | +LL | let x: /* Type */ = match () { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/match/match-vec-mismatch-2.rs b/tests/ui/match/match-vec-mismatch-2.rs new file mode 100644 index 000000000..553095837 --- /dev/null +++ b/tests/ui/match/match-vec-mismatch-2.rs @@ -0,0 +1,6 @@ +fn main() { + match () { + [()] => { } + //~^ ERROR expected an array or slice, found `()` + } +} diff --git a/tests/ui/match/match-vec-mismatch-2.stderr b/tests/ui/match/match-vec-mismatch-2.stderr new file mode 100644 index 000000000..5247bea62 --- /dev/null +++ b/tests/ui/match/match-vec-mismatch-2.stderr @@ -0,0 +1,9 @@ +error[E0529]: expected an array or slice, found `()` + --> $DIR/match-vec-mismatch-2.rs:3:9 + | +LL | [()] => { } + | ^^^^ pattern cannot match with input type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0529`. diff --git a/tests/ui/match/match-wildcards.rs b/tests/ui/match/match-wildcards.rs new file mode 100644 index 000000000..43f6e4913 --- /dev/null +++ b/tests/ui/match/match-wildcards.rs @@ -0,0 +1,21 @@ +// run-fail +// error-pattern:squirrelcupcake +// ignore-emscripten no processes + +fn cmp() -> isize { + match (Some('a'), None::) { + (Some(_), _) => { + panic!("squirrelcupcake"); + } + (_, Some(_)) => { + panic!(); + } + _ => { + panic!("wat"); + } + } +} + +fn main() { + println!("{}", cmp()); +} diff --git a/tests/ui/match/match_non_exhaustive.rs b/tests/ui/match/match_non_exhaustive.rs new file mode 100644 index 000000000..f162dd60f --- /dev/null +++ b/tests/ui/match/match_non_exhaustive.rs @@ -0,0 +1,32 @@ +// aux-build:match_non_exhaustive_lib.rs + +/* The error message for non-exhaustive matches on non-local enums + * marked as non-exhaustive should mention the fact that the enum + * is marked as non-exhaustive (issue #85227). + */ + +// Ignore non_exhaustive in the same crate +#[non_exhaustive] +enum L { A, B } + +extern crate match_non_exhaustive_lib; +use match_non_exhaustive_lib::{E1, E2}; + +fn foo() -> L {todo!()} +fn bar() -> (E1, E2) {todo!()} + +fn main() { + let l = foo(); + // No error for enums defined in this crate + match l { L::A => (), L::B => () }; + // (except if the match is already non-exhaustive) + match l { L::A => () }; + //~^ ERROR: non-exhaustive patterns: `L::B` not covered [E0004] + + // E1 is not visibly uninhabited from here + let (e1, e2) = bar(); + match e1 {}; + //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004] + match e2 { E2::A => (), E2::B => () }; + //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004] +} diff --git a/tests/ui/match/match_non_exhaustive.stderr b/tests/ui/match/match_non_exhaustive.stderr new file mode 100644 index 000000000..46ee8d517 --- /dev/null +++ b/tests/ui/match/match_non_exhaustive.stderr @@ -0,0 +1,56 @@ +error[E0004]: non-exhaustive patterns: `L::B` not covered + --> $DIR/match_non_exhaustive.rs:23:11 + | +LL | match l { L::A => () }; + | ^ pattern `L::B` not covered + | +note: `L` defined here + --> $DIR/match_non_exhaustive.rs:10:13 + | +LL | enum L { A, B } + | - ^ not covered + = note: the matched value is of type `L` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match l { L::A => (), L::B => todo!() }; + | +++++++++++++++++ + +error[E0004]: non-exhaustive patterns: type `E1` is non-empty + --> $DIR/match_non_exhaustive.rs:28:11 + | +LL | match e1 {}; + | ^^ + | +note: `E1` defined here + --> $DIR/auxiliary/match_non_exhaustive_lib.rs:2:1 + | +LL | pub enum E1 {} + | ^^^^^^^^^^^ + = note: the matched value is of type `E1`, which is marked as non-exhaustive +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match e1 { +LL + _ => todo!(), +LL ~ }; + | + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/match_non_exhaustive.rs:30:11 + | +LL | match e2 { E2::A => (), E2::B => () }; + | ^^ pattern `_` not covered + | +note: `E2` defined here + --> $DIR/auxiliary/match_non_exhaustive_lib.rs:5:1 + | +LL | pub enum E2 { A, B } + | ^^^^^^^^^^^ + = note: the matched value is of type `E2`, which is marked as non-exhaustive +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match e2 { E2::A => (), E2::B => (), _ => todo!() }; + | ++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/tests/ui/match/pattern-deref-miscompile.rs b/tests/ui/match/pattern-deref-miscompile.rs new file mode 100644 index 000000000..caa6d184a --- /dev/null +++ b/tests/ui/match/pattern-deref-miscompile.rs @@ -0,0 +1,46 @@ +// run-pass + +fn main() { + match b"." as &[u8] { + b"." if true => {}, + b"." => panic!(), + b".." => panic!(), + b"" => panic!(), + _ => panic!(), + } + match b"." as &[u8] { + b"." if false => panic!(), + b"." => {}, + b".." => panic!(), + b"" => panic!(), + _ => panic!(), + } + match b".." as &[u8] { + b"." if true => panic!(), // the miscompile caused this arm to be reached + b"." => panic!(), + b".." => {}, + b"" => panic!(), + _ => panic!(), + } + match b".." as &[u8] { + b"." if false => panic!(), + b"." => panic!(), + b".." => {}, + b"" => panic!(), + _ => panic!(), + } + match b"" as &[u8] { + b"." if true => panic!(), + b"." => panic!(), + b".." => panic!(), + b"" => {}, + _ => panic!(), + } + match b"" as &[u8] { + b"." if false => panic!(), + b"." => panic!(), + b".." => panic!(), + b"" => {}, + _ => panic!(), + } +} diff --git a/tests/ui/match/single-line.rs b/tests/ui/match/single-line.rs new file mode 100644 index 000000000..0f69d089f --- /dev/null +++ b/tests/ui/match/single-line.rs @@ -0,0 +1,3 @@ +fn main() { + let _ = match Some(42) { Some(x) => x, None => "" }; //~ ERROR E0308 +} diff --git a/tests/ui/match/single-line.stderr b/tests/ui/match/single-line.stderr new file mode 100644 index 000000000..ec3b76e3f --- /dev/null +++ b/tests/ui/match/single-line.stderr @@ -0,0 +1,12 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/single-line.rs:2:52 + | +LL | let _ = match Some(42) { Some(x) => x, None => "" }; + | -------------- - ^^ expected integer, found `&str` + | | | + | | this is found to be of type `{integer}` + | `match` arms have incompatible types + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit v1.2.3