From 54561148581f002793ab42893de4e3f7c26bd7ed Mon Sep 17 00:00:00 2001 From: Matthew Kuo Date: Wed, 4 Mar 2020 01:09:53 -0600 Subject: [PATCH 1/3] test(pattern): add tests for combinations of pattern features Reference issue #67311 Tests combinations of the following pattern features: - bindings_after_at - or_patterns - slice_patterns - box_patterns --- src/test/ui/or-patterns/box-patterns.rs | 37 +++++++++++++++ src/test/ui/or-patterns/slice-patterns.rs | 42 +++++++++++++++++ .../pattern/bindings-after-at/box-patterns.rs | 36 +++++++++++++++ .../or-patterns-box-patterns.rs | 45 +++++++++++++++++++ .../or-patterns-slice-patterns.rs | 43 ++++++++++++++++++ .../pattern/bindings-after-at/or-patterns.rs | 40 +++++++++++++++++ .../bindings-after-at/slice-patterns.rs | 40 +++++++++++++++++ 7 files changed, 283 insertions(+) create mode 100644 src/test/ui/or-patterns/box-patterns.rs create mode 100644 src/test/ui/or-patterns/slice-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/box-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/or-patterns.rs create mode 100644 src/test/ui/pattern/bindings-after-at/slice-patterns.rs diff --git a/src/test/ui/or-patterns/box-patterns.rs b/src/test/ui/or-patterns/box-patterns.rs new file mode 100644 index 0000000000000..aafd47993836c --- /dev/null +++ b/src/test/ui/or-patterns/box-patterns.rs @@ -0,0 +1,37 @@ +// Test or-patterns with box-patterns + +// run-pass + +#![feature(or_patterns)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(x: Option>) -> MatchArm { + match x { + Some(box Test::Foo | box Test::Bar) => MatchArm::Arm(0), + Some(box Test::Baz) => MatchArm::Arm(1), + Some(_) => MatchArm::Arm(2), + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(2)); + assert_eq!(test(None), MatchArm::Wild); +} diff --git a/src/test/ui/or-patterns/slice-patterns.rs b/src/test/ui/or-patterns/slice-patterns.rs new file mode 100644 index 0000000000000..2f2e865d98528 --- /dev/null +++ b/src/test/ui/or-patterns/slice-patterns.rs @@ -0,0 +1,42 @@ +// Test or-patterns with slice-patterns + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: &[Option]) -> MatchArm { + match foo { + [.., Some(Test::Foo | Test::Qux)] => MatchArm::Arm(0), + [Some(Test::Foo), .., Some(Test::Bar | Test::Baz)] => MatchArm::Arm(1), + [.., Some(Test::Bar | Test::Baz), _] => MatchArm::Arm(2), + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![ + Some(Test::Foo), + Some(Test::Bar), + Some(Test::Baz), + Some(Test::Qux), + ]; + + assert_eq!(test(&foo), MatchArm::Arm(0)); + assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + assert_eq!(test(&foo[1..3]), MatchArm::Arm(2)); + assert_eq!(test(&foo[4..]), MatchArm::Wild); +} diff --git a/src/test/ui/pattern/bindings-after-at/box-patterns.rs b/src/test/ui/pattern/bindings-after-at/box-patterns.rs new file mode 100644 index 0000000000000..ef9669a6b9e5a --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/box-patterns.rs @@ -0,0 +1,36 @@ +// Test bindings-after-at with box-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +fn test(x: Option>) -> MatchArm { + match x { + ref bar @ Some(box n) if n > 0 => { + // bar is a &Option> + assert_eq!(bar, &x); + + MatchArm::Arm(0) + }, + Some(ref bar @ box n) if n < 0 => { + // bar is a &Box here + assert_eq!(**bar, n); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(2))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(-1))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(0))), MatchArm::Wild); +} diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs new file mode 100644 index 0000000000000..ca8826f03f1ad --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs @@ -0,0 +1,45 @@ +// Test bindings-after-at with or-patterns and box-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: Option>) -> MatchArm { + match foo { + ref bar @ Some(box Test::Foo | box Test::Bar) => { + assert_eq!(bar, &foo); + + MatchArm::Arm(0) + }, + Some(ref bar @ box Test::Baz | ref bar @ box Test::Qux) => { + assert!(**bar == Test::Baz || **bar == Test::Qux); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(1)); + assert_eq!(test(None), MatchArm::Wild); +} diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs new file mode 100644 index 0000000000000..154df74cc33d8 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs @@ -0,0 +1,43 @@ +// Test bindings-after-at with or-patterns and slice-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: &[Option]) -> MatchArm { + match foo { + bar @ [Some(Test::Foo), .., Some(Test::Foo | Test::Qux)] => { + assert_eq!(bar, foo); + + MatchArm::Arm(0) + }, + [.., bar @ Some(Test::Bar | Test::Qux), _] => { + assert!(bar == &Some(Test::Bar) || bar == &Some(Test::Qux)); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![Some(Test::Foo), Some(Test::Bar), Some(Test::Baz), Some(Test::Qux)]; + assert_eq!(test(&foo), MatchArm::Arm(0)); + assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + assert_eq!(test(&foo[1..2]), MatchArm::Wild); +} diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns.rs new file mode 100644 index 0000000000000..a0e14004ab1b0 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/or-patterns.rs @@ -0,0 +1,40 @@ +// Test bindings-after-at with or-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: Option) -> MatchArm { + match foo { + bar @ Some(Test::Foo | Test::Bar) => { + assert!(bar == Some(Test::Foo) || bar == Some(Test::Bar)); + + MatchArm::Arm(0) + }, + Some(_) => MatchArm::Arm(1), + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Test::Foo)), MatchArm::Arm(0)); + assert_eq!(test(Some(Test::Bar)), MatchArm::Arm(0)); + assert_eq!(test(Some(Test::Baz)), MatchArm::Arm(1)); + assert_eq!(test(Some(Test::Qux)), MatchArm::Arm(1)); + assert_eq!(test(None), MatchArm::Wild); +} diff --git a/src/test/ui/pattern/bindings-after-at/slice-patterns.rs b/src/test/ui/pattern/bindings-after-at/slice-patterns.rs new file mode 100644 index 0000000000000..7e50527af0b97 --- /dev/null +++ b/src/test/ui/pattern/bindings-after-at/slice-patterns.rs @@ -0,0 +1,40 @@ +// Test bindings-after-at with slice-patterns + +// run-pass + +#![feature(bindings_after_at)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +fn test(foo: &[i32]) -> MatchArm { + match foo { + [bar @ .., n] if n == &5 => { + for i in bar { + assert!(i < &5); + } + + MatchArm::Arm(0) + }, + bar @ [x0, .., xn] => { + assert_eq!(x0, &1); + assert_eq!(x0, &1); + assert_eq!(xn, &4); + assert_eq!(bar, &[1, 2, 3, 4]); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![1, 2, 3, 4, 5]; + + assert_eq!(test(&foo), MatchArm::Arm(0)); + assert_eq!(test(&foo[..4]), MatchArm::Arm(1)); + assert_eq!(test(&foo[0..1]), MatchArm::Wild); +} From b4788a739b5dd040a969135bf46dc633c39fce16 Mon Sep 17 00:00:00 2001 From: Matthew Kuo Date: Wed, 4 Mar 2020 01:33:32 -0600 Subject: [PATCH 2/3] test(pattern): harden tests for or-patterns with slice-patterns Some of the nested OR paths were being missed --- src/test/ui/or-patterns/slice-patterns.rs | 14 ++++++++++++-- .../or-patterns-slice-patterns.rs | 17 +++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/test/ui/or-patterns/slice-patterns.rs b/src/test/ui/or-patterns/slice-patterns.rs index 2f2e865d98528..2526f048655ae 100644 --- a/src/test/ui/or-patterns/slice-patterns.rs +++ b/src/test/ui/or-patterns/slice-patterns.rs @@ -20,8 +20,8 @@ enum Test { fn test(foo: &[Option]) -> MatchArm { match foo { - [.., Some(Test::Foo | Test::Qux)] => MatchArm::Arm(0), - [Some(Test::Foo), .., Some(Test::Bar | Test::Baz)] => MatchArm::Arm(1), + [.., Some(Test::Qux | Test::Foo)] => MatchArm::Arm(0), + [Some(Test::Foo), .., Some(Test::Baz | Test::Bar)] => MatchArm::Arm(1), [.., Some(Test::Bar | Test::Baz), _] => MatchArm::Arm(2), _ => MatchArm::Wild, } @@ -35,8 +35,18 @@ fn main() { Some(Test::Qux), ]; + // path 1a assert_eq!(test(&foo), MatchArm::Arm(0)); + // path 1b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0)); + // path 2a assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + // path 2b + assert_eq!(test(&[Some(Test::Foo), Some(Test::Foo), Some(Test::Bar)]), MatchArm::Arm(1)); + // path 3a assert_eq!(test(&foo[1..3]), MatchArm::Arm(2)); + // path 3b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]), MatchArm::Arm(2)); + // path 4 assert_eq!(test(&foo[4..]), MatchArm::Wild); } diff --git a/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs index 154df74cc33d8..65c2b3741b3e3 100644 --- a/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs +++ b/src/test/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs @@ -21,7 +21,7 @@ enum Test { fn test(foo: &[Option]) -> MatchArm { match foo { - bar @ [Some(Test::Foo), .., Some(Test::Foo | Test::Qux)] => { + bar @ [Some(Test::Foo), .., Some(Test::Qux | Test::Foo)] => { assert_eq!(bar, foo); MatchArm::Arm(0) @@ -36,8 +36,21 @@ fn test(foo: &[Option]) -> MatchArm { } fn main() { - let foo = vec![Some(Test::Foo), Some(Test::Bar), Some(Test::Baz), Some(Test::Qux)]; + let foo = vec![ + Some(Test::Foo), + Some(Test::Bar), + Some(Test::Baz), + Some(Test::Qux), + ]; + + // path 1a assert_eq!(test(&foo), MatchArm::Arm(0)); + // path 1b + assert_eq!(test(&[Some(Test::Foo), Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0)); + // path 2a assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + // path 2b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Qux), Some(Test::Baz)]), MatchArm::Arm(1)); + // path 3 assert_eq!(test(&foo[1..2]), MatchArm::Wild); } From ea7b3c3c7bfbde2fc900f686b2dcd6ef03fcc510 Mon Sep 17 00:00:00 2001 From: Matthew Kuo Date: Wed, 4 Mar 2020 02:05:23 -0600 Subject: [PATCH 3/3] fix tidy error --- src/test/ui/or-patterns/slice-patterns.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/or-patterns/slice-patterns.rs b/src/test/ui/or-patterns/slice-patterns.rs index 2526f048655ae..05c907e824679 100644 --- a/src/test/ui/or-patterns/slice-patterns.rs +++ b/src/test/ui/or-patterns/slice-patterns.rs @@ -46,7 +46,8 @@ fn main() { // path 3a assert_eq!(test(&foo[1..3]), MatchArm::Arm(2)); // path 3b - assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]), MatchArm::Arm(2)); + assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]), + MatchArm::Arm(2)); // path 4 assert_eq!(test(&foo[4..]), MatchArm::Wild); }