summaryrefslogtreecommitdiffstats
path: root/tests/ui/half-open-range-patterns
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/half-open-range-patterns
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/half-open-range-patterns')
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs10
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr14
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs11
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr21
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs11
-rw-r--r--tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr40
-rw-r--r--tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs7
-rw-r--r--tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr12
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs7
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr21
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs167
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr819
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs48
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs30
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr37
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs24
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr59
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs24
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr55
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs159
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs29
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs53
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr159
-rw-r--r--tests/ui/half-open-range-patterns/pat-tuple-4.rs12
-rw-r--r--tests/ui/half-open-range-patterns/pat-tuple-5.rs9
-rw-r--r--tests/ui/half-open-range-patterns/pat-tuple-5.stderr14
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions0.rs31
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.rs29
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr36
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.rs21
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr17
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions3.rs23
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions3.stderr48
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs16
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr9
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs8
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr30
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs10
38 files changed, 2130 insertions, 0 deletions
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs
new file mode 100644
index 000000000..b2e9ffb57
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs
@@ -0,0 +1,10 @@
+#![feature(half_open_range_patterns_in_slices)]
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ match [5..4, 99..105, 43..44] {
+ [_, 99.., _] => {},
+ //~^ ERROR mismatched types
+ _ => {},
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr
new file mode 100644
index 000000000..095a1c6af
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/exclusive_range_pattern_syntax_collision.rs:6:13
+ |
+LL | match [5..4, 99..105, 43..44] {
+ | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
+LL | [_, 99.., _] => {},
+ | ^^ expected struct `Range`, found integer
+ |
+ = note: expected struct `std::ops::Range<{integer}>`
+ found type `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs
new file mode 100644
index 000000000..20f4d8f88
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs
@@ -0,0 +1,11 @@
+#![feature(half_open_range_patterns_in_slices)]
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ match [5..4, 99..105, 43..44] {
+ [_, 99..] => {},
+ //~^ ERROR pattern requires 2 elements but array has 3
+ //~| ERROR mismatched types
+ _ => {},
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr
new file mode 100644
index 000000000..2ea3205dc
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.stderr
@@ -0,0 +1,21 @@
+error[E0527]: pattern requires 2 elements but array has 3
+ --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:9
+ |
+LL | [_, 99..] => {},
+ | ^^^^^^^^^ expected 3 elements
+
+error[E0308]: mismatched types
+ --> $DIR/exclusive_range_pattern_syntax_collision2.rs:6:13
+ |
+LL | match [5..4, 99..105, 43..44] {
+ | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
+LL | [_, 99..] => {},
+ | ^^ expected struct `Range`, found integer
+ |
+ = note: expected struct `std::ops::Range<{integer}>`
+ found type `{integer}`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0527.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs
new file mode 100644
index 000000000..14ca07d0a
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs
@@ -0,0 +1,11 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ match [5..4, 99..105, 43..44] {
+ [..9, 99..100, _] => {},
+ //~^ ERROR mismatched types
+ //~| ERROR mismatched types
+ //~| ERROR mismatched types
+ _ => {},
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr
new file mode 100644
index 000000000..bbdf0c83f
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.stderr
@@ -0,0 +1,40 @@
+error[E0308]: mismatched types
+ --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12
+ |
+LL | match [5..4, 99..105, 43..44] {
+ | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
+LL | [..9, 99..100, _] => {},
+ | ^ expected struct `Range`, found integer
+ |
+ = note: expected struct `std::ops::Range<{integer}>`
+ found type `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15
+ |
+LL | match [5..4, 99..105, 43..44] {
+ | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
+LL | [..9, 99..100, _] => {},
+ | ^^ --- this is of type `{integer}`
+ | |
+ | expected struct `Range`, found integer
+ |
+ = note: expected struct `std::ops::Range<{integer}>`
+ found type `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19
+ |
+LL | match [5..4, 99..105, 43..44] {
+ | ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
+LL | [..9, 99..100, _] => {},
+ | -- ^^^ expected struct `Range`, found integer
+ | |
+ | this is of type `{integer}`
+ |
+ = note: expected struct `std::ops::Range<{integer}>`
+ found type `{integer}`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs
new file mode 100644
index 000000000..dac973473
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs
@@ -0,0 +1,7 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let xs = [13, 1, 5, 2, 3, 1, 21, 8];
+ let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ //~^ `X..` patterns in slices are experimental
+}
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
new file mode 100644
index 000000000..ee5b0e11c
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
@@ -0,0 +1,12 @@
+error[E0658]: `X..` patterns in slices are experimental
+ --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:5:10
+ |
+LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ | ^^^^^^^
+ |
+ = note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
+ = help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs
new file mode 100644
index 000000000..17ea2b13f
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs
@@ -0,0 +1,7 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let "a".. = "a"; //~ ERROR only `char` and numeric types are allowed in range patterns
+ let .."a" = "a"; //~ ERROR only `char` and numeric types are allowed in range patterns
+ let ..="a" = "a"; //~ ERROR only `char` and numeric types are allowed in range patterns
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr
new file mode 100644
index 000000000..f7c59a196
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-bad-types.stderr
@@ -0,0 +1,21 @@
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/half-open-range-pats-bad-types.rs:4:9
+ |
+LL | let "a".. = "a";
+ | ^^^ 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/half-open-range-pats-bad-types.rs:5:11
+ |
+LL | let .."a" = "a";
+ | ^^^ 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/half-open-range-pats-bad-types.rs:6:12
+ |
+LL | let ..="a" = "a";
+ | ^^^ this is of type `&'static str` but it should be `char` or numeric
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0029`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs
new file mode 100644
index 000000000..a2a4c62fa
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs
@@ -0,0 +1,167 @@
+// Test various non-exhaustive matches for `X..`, `..=X` and `..X` ranges.
+
+#![feature(exclusive_range_pattern)]
+#![allow(illegal_floating_point_literal_pattern)]
+
+fn main() {}
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+fn floats() {
+ m!(0f32, f32::NEG_INFINITY..); //~ ERROR non-exhaustive patterns: `_` not covered
+ m!(0f32, ..f32::INFINITY); //~ ERROR non-exhaustive patterns: `_` not covered
+}
+
+fn khar() {
+ const ALMOST_MAX: char = '\u{10fffe}';
+ const ALMOST_MIN: char = '\u{1}';
+ const VAL: char = 'a';
+ const VAL_1: char = 'b';
+ const VAL_2: char = 'c';
+ m!('a', ..core::char::MAX); //~ ERROR non-exhaustive patterns
+ m!('a', ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!('a', ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!('a', ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!('a', ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!('a', ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+}
+
+mod unsigned {
+ fn u8() {
+ const ALMOST_MAX: u8 = u8::MAX - 1;
+ const ALMOST_MIN: u8 = u8::MIN + 1;
+ const VAL: u8 = 42;
+ const VAL_1: u8 = VAL + 1;
+ const VAL_2: u8 = VAL + 2;
+ m!(0, ..u8::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn u16() {
+ const ALMOST_MAX: u16 = u16::MAX - 1;
+ const ALMOST_MIN: u16 = u16::MIN + 1;
+ const VAL: u16 = 42;
+ const VAL_1: u16 = VAL + 1;
+ const VAL_2: u16 = VAL + 2;
+ m!(0, ..u16::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn u32() {
+ const ALMOST_MAX: u32 = u32::MAX - 1;
+ const ALMOST_MIN: u32 = u32::MIN + 1;
+ const VAL: u32 = 42;
+ const VAL_1: u32 = VAL + 1;
+ const VAL_2: u32 = VAL + 2;
+ m!(0, ..u32::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn u64() {
+ const ALMOST_MAX: u64 = u64::MAX - 1;
+ const ALMOST_MIN: u64 = u64::MIN + 1;
+ const VAL: u64 = 42;
+ const VAL_1: u64 = VAL + 1;
+ const VAL_2: u64 = VAL + 2;
+ m!(0, ..u64::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn u128() {
+ const ALMOST_MAX: u128 = u128::MAX - 1;
+ const ALMOST_MIN: u128 = u128::MIN + 1;
+ const VAL: u128 = 42;
+ const VAL_1: u128 = VAL + 1;
+ const VAL_2: u128 = VAL + 2;
+ m!(0, ..u128::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+}
+
+mod signed {
+ fn i8() {
+ const ALMOST_MAX: i8 = i8::MAX - 1;
+ const ALMOST_MIN: i8 = i8::MIN + 1;
+ const VAL: i8 = 42;
+ const VAL_1: i8 = VAL + 1;
+ const VAL_2: i8 = VAL + 2;
+ m!(0, ..i8::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn i16() {
+ const ALMOST_MAX: i16 = i16::MAX - 1;
+ const ALMOST_MIN: i16 = i16::MIN + 1;
+ const VAL: i16 = 42;
+ const VAL_1: i16 = VAL + 1;
+ const VAL_2: i16 = VAL + 2;
+ m!(0, ..i16::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn i32() {
+ const ALMOST_MAX: i32 = i32::MAX - 1;
+ const ALMOST_MIN: i32 = i32::MIN + 1;
+ const VAL: i32 = 42;
+ const VAL_1: i32 = VAL + 1;
+ const VAL_2: i32 = VAL + 2;
+ m!(0, ..i32::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn i64() {
+ const ALMOST_MAX: i64 = i64::MAX - 1;
+ const ALMOST_MIN: i64 = i64::MIN + 1;
+ const VAL: i64 = 42;
+ const VAL_1: i64 = VAL + 1;
+ const VAL_2: i64 = VAL + 2;
+ m!(0, ..i64::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+ fn i128() {
+ const ALMOST_MAX: i128 = i128::MAX - 1;
+ const ALMOST_MIN: i128 = i128::MIN + 1;
+ const VAL: i128 = 42;
+ const VAL_1: i128 = VAL + 1;
+ const VAL_2: i128 = VAL + 2;
+ m!(0, ..i128::MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ALMOST_MIN..); //~ ERROR non-exhaustive patterns
+ m!(0, ..=ALMOST_MAX); //~ ERROR non-exhaustive patterns
+ m!(0, ..=VAL | VAL_2..); //~ ERROR non-exhaustive patterns
+ m!(0, ..VAL_1 | VAL_2..); //~ ERROR non-exhaustive patterns
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
new file mode 100644
index 000000000..6b20a820b
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.stderr
@@ -0,0 +1,819 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:15:8
+ |
+LL | m!(0f32, f32::NEG_INFINITY..);
+ | ^^^^ pattern `_` not covered
+ |
+ = note: the matched value is of type `f32`
+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 $s { $($t)+ => {}, _ => todo!() }
+ | ++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:16:8
+ |
+LL | m!(0f32, ..f32::INFINITY);
+ | ^^^^ pattern `_` not covered
+ |
+ = note: the matched value is of type `f32`
+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 $s { $($t)+ => {}, _ => todo!() }
+ | ++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:25:8
+ |
+LL | m!('a', ..core::char::MAX);
+ | ^^^ pattern `'\u{10ffff}'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, '\u{10ffff}' => todo!() }
+ | +++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'\u{10fffe}'..='\u{10ffff}'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:26:8
+ |
+LL | m!('a', ..ALMOST_MAX);
+ | ^^^ pattern `'\u{10fffe}'..='\u{10ffff}'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, '\u{10fffe}'..='\u{10ffff}' => todo!() }
+ | ++++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'\0'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:27:8
+ |
+LL | m!('a', ALMOST_MIN..);
+ | ^^^ pattern `'\0'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, '\0' => todo!() }
+ | +++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'\u{10ffff}'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:28:8
+ |
+LL | m!('a', ..=ALMOST_MAX);
+ | ^^^ pattern `'\u{10ffff}'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, '\u{10ffff}' => todo!() }
+ | +++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'b'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:29:8
+ |
+LL | m!('a', ..=VAL | VAL_2..);
+ | ^^^ pattern `'b'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, 'b' => todo!() }
+ | ++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `'b'` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:30:8
+ |
+LL | m!('a', ..VAL_1 | VAL_2..);
+ | ^^^ pattern `'b'` not covered
+ |
+ = note: the matched value is of type `char`
+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 $s { $($t)+ => {}, 'b' => todo!() }
+ | ++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:40:12
+ |
+LL | m!(0, ..u8::MAX);
+ | ^ pattern `u8::MAX` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, u8::MAX => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `254_u8..=u8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:41:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `254_u8..=u8::MAX` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, 254_u8..=u8::MAX => todo!() }
+ | +++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `0_u8` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:42:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `0_u8` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, 0_u8 => todo!() }
+ | +++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:43:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `u8::MAX` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, u8::MAX => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u8` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:44:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_u8` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, 43_u8 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u8` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:45:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_u8` not covered
+ |
+ = note: the matched value is of type `u8`
+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 $s { $($t)+ => {}, 43_u8 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:53:12
+ |
+LL | m!(0, ..u16::MAX);
+ | ^ pattern `u16::MAX` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, u16::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `65534_u16..=u16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:54:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `65534_u16..=u16::MAX` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, 65534_u16..=u16::MAX => todo!() }
+ | +++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `0_u16` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:55:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `0_u16` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, 0_u16 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:56:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `u16::MAX` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, u16::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u16` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:57:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_u16` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, 43_u16 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u16` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:58:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_u16` not covered
+ |
+ = note: the matched value is of type `u16`
+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 $s { $($t)+ => {}, 43_u16 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:66:12
+ |
+LL | m!(0, ..u32::MAX);
+ | ^ pattern `u32::MAX` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, u32::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `4294967294_u32..=u32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:67:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `4294967294_u32..=u32::MAX` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, 4294967294_u32..=u32::MAX => todo!() }
+ | ++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `0_u32` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:68:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `0_u32` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, 0_u32 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:69:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `u32::MAX` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, u32::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u32` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:70:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_u32` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, 43_u32 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u32` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:71:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_u32` not covered
+ |
+ = note: the matched value is of type `u32`
+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 $s { $($t)+ => {}, 43_u32 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:79:12
+ |
+LL | m!(0, ..u64::MAX);
+ | ^ pattern `u64::MAX` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, u64::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `18446744073709551614_u64..=u64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:80:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `18446744073709551614_u64..=u64::MAX` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, 18446744073709551614_u64..=u64::MAX => todo!() }
+ | ++++++++++++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `0_u64` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:81:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `0_u64` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, 0_u64 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:82:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `u64::MAX` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, u64::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u64` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:83:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_u64` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, 43_u64 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u64` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:84:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_u64` not covered
+ |
+ = note: the matched value is of type `u64`
+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 $s { $($t)+ => {}, 43_u64 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:92:12
+ |
+LL | m!(0, ..u128::MAX);
+ | ^ pattern `u128::MAX` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, u128::MAX => todo!() }
+ | ++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211454_u128..=u128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:93:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `340282366920938463463374607431768211454_u128..=u128::MAX` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, 340282366920938463463374607431768211454_u128..=u128::MAX => todo!() }
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `0_u128` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:94:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `0_u128` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, 0_u128 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:95:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `u128::MAX` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, u128::MAX => todo!() }
+ | ++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u128` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:96:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_u128` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, 43_u128 => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_u128` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:97:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_u128` not covered
+ |
+ = note: the matched value is of type `u128`
+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 $s { $($t)+ => {}, 43_u128 => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:108:12
+ |
+LL | m!(0, ..i8::MAX);
+ | ^ pattern `i8::MAX` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, i8::MAX => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `126_i8..=i8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:109:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `126_i8..=i8::MAX` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, 126_i8..=i8::MAX => todo!() }
+ | +++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i8::MIN` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:110:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `i8::MIN` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, i8::MIN => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i8::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:111:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `i8::MAX` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, i8::MAX => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i8` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:112:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_i8` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, 43_i8 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i8` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:113:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_i8` not covered
+ |
+ = note: the matched value is of type `i8`
+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 $s { $($t)+ => {}, 43_i8 => todo!() }
+ | ++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:121:12
+ |
+LL | m!(0, ..i16::MAX);
+ | ^ pattern `i16::MAX` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, i16::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `32766_i16..=i16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:122:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `32766_i16..=i16::MAX` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, 32766_i16..=i16::MAX => todo!() }
+ | +++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i16::MIN` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:123:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `i16::MIN` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, i16::MIN => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i16::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:124:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `i16::MAX` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, i16::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i16` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:125:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_i16` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, 43_i16 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i16` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:126:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_i16` not covered
+ |
+ = note: the matched value is of type `i16`
+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 $s { $($t)+ => {}, 43_i16 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:134:12
+ |
+LL | m!(0, ..i32::MAX);
+ | ^ pattern `i32::MAX` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, i32::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `2147483646_i32..=i32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:135:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `2147483646_i32..=i32::MAX` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, 2147483646_i32..=i32::MAX => todo!() }
+ | ++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i32::MIN` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:136:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `i32::MIN` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, i32::MIN => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i32::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:137:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `i32::MAX` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, i32::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i32` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:138:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_i32` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, 43_i32 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i32` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:139:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_i32` not covered
+ |
+ = note: the matched value is of type `i32`
+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 $s { $($t)+ => {}, 43_i32 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:147:12
+ |
+LL | m!(0, ..i64::MAX);
+ | ^ pattern `i64::MAX` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, i64::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `9223372036854775806_i64..=i64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:148:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `9223372036854775806_i64..=i64::MAX` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, 9223372036854775806_i64..=i64::MAX => todo!() }
+ | +++++++++++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i64::MIN` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:149:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `i64::MIN` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, i64::MIN => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i64::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:150:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `i64::MAX` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, i64::MAX => todo!() }
+ | +++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i64` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:151:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_i64` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, 43_i64 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i64` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:152:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_i64` not covered
+ |
+ = note: the matched value is of type `i64`
+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 $s { $($t)+ => {}, 43_i64 => todo!() }
+ | +++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:160:12
+ |
+LL | m!(0, ..i128::MAX);
+ | ^ pattern `i128::MAX` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, i128::MAX => todo!() }
+ | ++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `170141183460469231731687303715884105726_i128..=i128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:161:12
+ |
+LL | m!(0, ..ALMOST_MAX);
+ | ^ pattern `170141183460469231731687303715884105726_i128..=i128::MAX` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, 170141183460469231731687303715884105726_i128..=i128::MAX => todo!() }
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i128::MIN` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:162:12
+ |
+LL | m!(0, ALMOST_MIN..);
+ | ^ pattern `i128::MIN` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, i128::MIN => todo!() }
+ | ++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `i128::MAX` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:163:12
+ |
+LL | m!(0, ..=ALMOST_MAX);
+ | ^ pattern `i128::MAX` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, i128::MAX => todo!() }
+ | ++++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i128` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:164:12
+ |
+LL | m!(0, ..=VAL | VAL_2..);
+ | ^ pattern `43_i128` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, 43_i128 => todo!() }
+ | ++++++++++++++++++++
+
+error[E0004]: non-exhaustive patterns: `43_i128` not covered
+ --> $DIR/half-open-range-pats-exhaustive-fail.rs:165:12
+ |
+LL | m!(0, ..VAL_1 | VAL_2..);
+ | ^ pattern `43_i128` not covered
+ |
+ = note: the matched value is of type `i128`
+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 $s { $($t)+ => {}, 43_i128 => todo!() }
+ | ++++++++++++++++++++
+
+error: aborting due to 68 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs
new file mode 100644
index 000000000..4b7eee134
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs
@@ -0,0 +1,48 @@
+// check-pass
+
+// Test various exhaustive matches for `X..`, `..=X` and `..X` ranges.
+
+#![feature(exclusive_range_pattern)]
+
+fn main() {}
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+macro_rules! test_int {
+ ($s:expr, $min:path, $max:path) => {
+ m!($s, $min..);
+ m!($s, $min..5 | 5..);
+ m!($s, ..5 | 5..);
+ m!($s, ..=4 | 5..);
+ m!($s, ..=$max);
+ m!($s, ..$max | $max);
+ m!(($s, true), (..5, true) | (5.., true) | ($min.., false));
+ }
+}
+
+fn unsigned_int() {
+ test_int!(0u8, u8::MIN, u8::MAX);
+ test_int!(0u16, u16::MIN, u16::MAX);
+ test_int!(0u32, u32::MIN, u32::MAX);
+ test_int!(0u64, u64::MIN, u64::MAX);
+ test_int!(0u128, u128::MIN, u128::MAX);
+}
+
+fn signed_int() {
+ test_int!(0i8, i8::MIN, i8::MAX);
+ test_int!(0i16, i16::MIN, i16::MAX);
+ test_int!(0i32, i32::MIN, i32::MAX);
+ test_int!(0i64, i64::MIN, i64::MAX);
+ test_int!(0i128, i128::MIN, i128::MAX);
+}
+
+fn khar() {
+ m!('a', ..=core::char::MAX);
+ m!('a', '\u{0}'..);
+ m!('a', ..='\u{D7FF}' | '\u{E000}'..);
+ m!('a', ..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..);
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs
new file mode 100644
index 000000000..526a797e9
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs
@@ -0,0 +1,30 @@
+// Test that `...X` range-to patterns are syntactically invalid.
+//
+// See https://github.com/rust-lang/rust/pull/67258#issuecomment-565656155
+// for the reason why. To summarize, we might want to introduce `...expr` as
+// an expression form for splatting (or "untupling") in an expression context.
+// While there is no syntactic ambiguity with `...X` in a pattern context,
+// there's a potential confusion factor here, and we would prefer to keep patterns
+// and expressions in-sync. As such, we do not allow `...X` in patterns either.
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ match scrutinee {
+ ...X => {} //~ ERROR range-to patterns with `...` are not allowed
+ ...0 => {} //~ ERROR range-to patterns with `...` are not allowed
+ ...'a' => {} //~ ERROR range-to patterns with `...` are not allowed
+ ...0.0f32 => {} //~ ERROR range-to patterns with `...` are not allowed
+ }
+}
+
+fn syntax2() {
+ macro_rules! mac {
+ ($e:expr) => {
+ let ...$e; //~ ERROR range-to patterns with `...` are not allowed
+ }
+ }
+
+ mac!(0);
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
new file mode 100644
index 000000000..ddffeaf97
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
@@ -0,0 +1,37 @@
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:15:9
+ |
+LL | ...X => {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:16:9
+ |
+LL | ...0 => {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:17:9
+ |
+LL | ...'a' => {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:18:9
+ |
+LL | ...0.0f32 => {}
+ | ^^^ help: use `..=` instead
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:25:17
+ |
+LL | let ...$e;
+ | ^^^ help: use `..=` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs
new file mode 100644
index 000000000..6567c8cc6
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs
@@ -0,0 +1,24 @@
+// Test `X...` and `X..=` range patterns not being allowed syntactically.
+// FIXME(Centril): perhaps these should be semantic restrictions.
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn foo() {
+ if let 0... = 1 {} //~ ERROR inclusive range with no end
+ if let 0..= = 1 {} //~ ERROR inclusive range with no end
+ const X: u8 = 0;
+ if let X... = 1 {} //~ ERROR inclusive range with no end
+ if let X..= = 1 {} //~ ERROR inclusive range with no end
+}
+
+fn bar() {
+ macro_rules! mac {
+ ($e:expr) => {
+ let $e...; //~ ERROR inclusive range with no end
+ let $e..=; //~ ERROR inclusive range with no end
+ }
+ }
+
+ mac!(0);
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
new file mode 100644
index 000000000..3ad84b0ef
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
@@ -0,0 +1,59 @@
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:8:13
+ |
+LL | if let 0... = 1 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:9:13
+ |
+LL | if let 0..= = 1 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:11:13
+ |
+LL | if let X... = 1 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:12:13
+ |
+LL | if let X..= = 1 {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:18:19
+ |
+LL | let $e...;
+ | ^^^ help: use `..` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-inclusive-no-end.rs:19:19
+ |
+LL | let $e..=;
+ | ^^^ help: use `..` instead
+...
+LL | mac!(0);
+ | ------- in this macro invocation
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+ = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs
new file mode 100644
index 000000000..2d63fe078
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs
@@ -0,0 +1,24 @@
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ match &0 {
+ &0.. | _ => {}
+ //~^ ERROR the range pattern here has ambiguous interpretation
+ &0..= | _ => {}
+ //~^ ERROR the range pattern here has ambiguous interpretation
+ //~| ERROR inclusive range with no end
+ &0... | _ => {}
+ //~^ ERROR inclusive range with no end
+ }
+
+ match &0 {
+ &..0 | _ => {}
+ //~^ ERROR the range pattern here has ambiguous interpretation
+ &..=0 | _ => {}
+ //~^ ERROR the range pattern here has ambiguous interpretation
+ &...0 | _ => {}
+ //~^ ERROR the range pattern here has ambiguous interpretation
+ //~| ERROR range-to patterns with `...` are not allowed
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr
new file mode 100644
index 000000000..111e81799
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.stderr
@@ -0,0 +1,55 @@
+error: the range pattern here has ambiguous interpretation
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:6:10
+ |
+LL | &0.. | _ => {}
+ | ^^^ help: add parentheses to clarify the precedence: `(0..)`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:8:11
+ |
+LL | &0..= | _ => {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: the range pattern here has ambiguous interpretation
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:8:10
+ |
+LL | &0..= | _ => {}
+ | ^^^^ help: add parentheses to clarify the precedence: `(0..=)`
+
+error[E0586]: inclusive range with no end
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:11:11
+ |
+LL | &0... | _ => {}
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: the range pattern here has ambiguous interpretation
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:16:10
+ |
+LL | &..0 | _ => {}
+ | ^^^ help: add parentheses to clarify the precedence: `(..0)`
+
+error: the range pattern here has ambiguous interpretation
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:18:10
+ |
+LL | &..=0 | _ => {}
+ | ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
+
+error: range-to patterns with `...` are not allowed
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:20:10
+ |
+LL | &...0 | _ => {}
+ | ^^^ help: use `..=` instead
+
+error: the range pattern here has ambiguous interpretation
+ --> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:20:10
+ |
+LL | &...0 | _ => {}
+ | ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs
new file mode 100644
index 000000000..6c6ba9319
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs
@@ -0,0 +1,159 @@
+// run-pass
+
+// Test half-open range patterns against their expression equivalents
+// via `.contains(...)` and make sure the dynamic semantics match.
+
+#![feature(exclusive_range_pattern)]
+#![allow(illegal_floating_point_literal_pattern)]
+#![allow(unreachable_patterns)]
+
+macro_rules! yes {
+ ($scrutinee:expr, $($t:tt)+) => {
+ {
+ let m = match $scrutinee { $($t)+ => true, _ => false, };
+ let c = ($($t)+).contains(&$scrutinee);
+ assert_eq!(m, c);
+ m
+ }
+ }
+}
+
+fn range_to_inclusive() {
+ // `..=X` (`RangeToInclusive`-equivalent):
+ //---------------------------------------
+
+ // u8; `..=X`
+ assert!(yes!(u8::MIN, ..=u8::MIN));
+ assert!(yes!(u8::MIN, ..=5));
+ assert!(yes!(5u8, ..=5));
+ assert!(!yes!(6u8, ..=5));
+
+ // i16; `..=X`
+ assert!(yes!(i16::MIN, ..=i16::MIN));
+ assert!(yes!(i16::MIN, ..=0));
+ assert!(yes!(i16::MIN, ..=-5));
+ assert!(yes!(-5, ..=-5));
+ assert!(!yes!(-4, ..=-5));
+
+ // char; `..=X`
+ assert!(yes!('\u{0}', ..='\u{0}'));
+ assert!(yes!('\u{0}', ..='a'));
+ assert!(yes!('a', ..='a'));
+ assert!(!yes!('b', ..='a'));
+
+ // f32; `..=X`
+ assert!(yes!(f32::NEG_INFINITY, ..=f32::NEG_INFINITY));
+ assert!(yes!(f32::NEG_INFINITY, ..=1.0f32));
+ assert!(yes!(1.5f32, ..=1.5f32));
+ assert!(!yes!(1.6f32, ..=-1.5f32));
+
+ // f64; `..=X`
+ assert!(yes!(f64::NEG_INFINITY, ..=f64::NEG_INFINITY));
+ assert!(yes!(f64::NEG_INFINITY, ..=1.0f64));
+ assert!(yes!(1.5f64, ..=1.5f64));
+ assert!(!yes!(1.6f64, ..=-1.5f64));
+}
+
+fn range_to() {
+ // `..X` (`RangeTo`-equivalent):
+ //-----------------------------
+
+ // u8; `..X`
+ assert!(yes!(0u8, ..1));
+ assert!(yes!(0u8, ..5));
+ assert!(!yes!(5u8, ..5));
+ assert!(!yes!(6u8, ..5));
+
+ // u8; `..X`
+ const NU8: u8 = u8::MIN + 1;
+ assert!(yes!(u8::MIN, ..NU8));
+ assert!(yes!(0u8, ..5));
+ assert!(!yes!(5u8, ..5));
+ assert!(!yes!(6u8, ..5));
+
+ // i16; `..X`
+ const NI16: i16 = i16::MIN + 1;
+ assert!(yes!(i16::MIN, ..NI16));
+ assert!(yes!(i16::MIN, ..5));
+ assert!(yes!(-6, ..-5));
+ assert!(!yes!(-5, ..-5));
+
+ // char; `..X`
+ assert!(yes!('\u{0}', ..'\u{1}'));
+ assert!(yes!('\u{0}', ..'a'));
+ assert!(yes!('a', ..'b'));
+ assert!(!yes!('a', ..'a'));
+ assert!(!yes!('b', ..'a'));
+
+ // f32; `..X`
+ assert!(yes!(f32::NEG_INFINITY, ..1.0f32));
+ assert!(!yes!(1.5f32, ..1.5f32));
+ const E32: f32 = 1.5f32 + f32::EPSILON;
+ assert!(yes!(1.5f32, ..E32));
+ assert!(!yes!(1.6f32, ..1.5f32));
+
+ // f64; `..X`
+ assert!(yes!(f64::NEG_INFINITY, ..1.0f64));
+ assert!(!yes!(1.5f64, ..1.5f64));
+ const E64: f64 = 1.5f64 + f64::EPSILON;
+ assert!(yes!(1.5f64, ..E64));
+ assert!(!yes!(1.6f64, ..1.5f64));
+}
+
+fn range_from() {
+ // `X..` (`RangeFrom`-equivalent):
+ //--------------------------------
+
+ // u8; `X..`
+ assert!(yes!(u8::MIN, u8::MIN..));
+ assert!(yes!(u8::MAX, u8::MIN..));
+ assert!(!yes!(u8::MIN, 1..));
+ assert!(!yes!(4, 5..));
+ assert!(yes!(5, 5..));
+ assert!(yes!(6, 5..));
+ assert!(yes!(u8::MAX, u8::MAX..));
+
+ // i16; `X..`
+ assert!(yes!(i16::MIN, i16::MIN..));
+ assert!(yes!(i16::MAX, i16::MIN..));
+ const NI16: i16 = i16::MIN + 1;
+ assert!(!yes!(i16::MIN, NI16..));
+ assert!(!yes!(-4, 5..));
+ assert!(yes!(-4, -4..));
+ assert!(yes!(-3, -4..));
+ assert!(yes!(i16::MAX, i16::MAX..));
+
+ // char; `X..`
+ assert!(yes!('\u{0}', '\u{0}'..));
+ assert!(yes!(core::char::MAX, '\u{0}'..));
+ assert!(yes!('a', 'a'..));
+ assert!(yes!('b', 'a'..));
+ assert!(!yes!('a', 'b'..));
+ assert!(yes!(core::char::MAX, core::char::MAX..));
+
+ // f32; `X..`
+ assert!(yes!(f32::NEG_INFINITY, f32::NEG_INFINITY..));
+ assert!(yes!(f32::INFINITY, f32::NEG_INFINITY..));
+ assert!(!yes!(f32::NEG_INFINITY, 1.0f32..));
+ assert!(yes!(f32::INFINITY, 1.0f32..));
+ assert!(!yes!(1.0f32 - f32::EPSILON, 1.0f32..));
+ assert!(yes!(1.0f32, 1.0f32..));
+ assert!(yes!(f32::INFINITY, 1.0f32..));
+ assert!(yes!(f32::INFINITY, f32::INFINITY..));
+
+ // f64; `X..`
+ assert!(yes!(f64::NEG_INFINITY, f64::NEG_INFINITY..));
+ assert!(yes!(f64::INFINITY, f64::NEG_INFINITY..));
+ assert!(!yes!(f64::NEG_INFINITY, 1.0f64..));
+ assert!(yes!(f64::INFINITY, 1.0f64..));
+ assert!(!yes!(1.0f64 - f64::EPSILON, 1.0f64..));
+ assert!(yes!(1.0f64, 1.0f64..));
+ assert!(yes!(f64::INFINITY, 1.0f64..));
+ assert!(yes!(f64::INFINITY, f64::INFINITY..));
+}
+
+fn main() {
+ range_to_inclusive();
+ range_to();
+ range_from();
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs
new file mode 100644
index 000000000..9a73e8906
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs
@@ -0,0 +1,29 @@
+// check-pass
+
+// Test the parsing of half-open ranges.
+
+#![feature(exclusive_range_pattern)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+ match scrutinee {
+ X.. | 0.. | 'a'.. | 0.0f32.. => {}
+ ..=X | ..X => {}
+ ..=0 | ..0 => {}
+ ..='a' | ..'a' => {}
+ ..=0.0f32 | ..0.0f32 => {}
+ }
+}
+
+fn syntax2() {
+ macro_rules! mac {
+ ($e:expr) => {
+ match 0u8 { ..$e => {}, _ => {} }
+ match 0u8 { ..=$e => {}, _ => {} }
+ match 0u8 { $e.. => {}, _ => {} }
+ }
+ }
+ mac!(42u8);
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs
new file mode 100644
index 000000000..f55566602
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs
@@ -0,0 +1,53 @@
+#![feature(exclusive_range_pattern)]
+#![allow(illegal_floating_point_literal_pattern)]
+
+macro_rules! m {
+ ($s:expr, $($t:tt)+) => {
+ match $s { $($t)+ => {} }
+ }
+}
+
+fn main() {
+ m!(0, ..u8::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..u16::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..u32::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..u64::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..u128::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+
+ m!(0, ..i8::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..i16::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..i32::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..i64::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0, ..i128::MIN);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+
+ m!(0f32, ..f32::NEG_INFINITY);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+ m!(0f64, ..f64::NEG_INFINITY);
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+
+ m!('a', ..'\u{0}');
+ //~^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+}
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr
new file mode 100644
index 000000000..56b224a85
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr
@@ -0,0 +1,159 @@
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:11:11
+ |
+LL | m!(0, ..u8::MIN);
+ | ^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11
+ |
+LL | m!(0, ..u16::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:17:11
+ |
+LL | m!(0, ..u32::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:20:11
+ |
+LL | m!(0, ..u64::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11
+ |
+LL | m!(0, ..u128::MIN);
+ | ^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11
+ |
+LL | m!(0, ..i8::MIN);
+ | ^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11
+ |
+LL | m!(0, ..i16::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:33:11
+ |
+LL | m!(0, ..i32::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:36:11
+ |
+LL | m!(0, ..i64::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:39:11
+ |
+LL | m!(0, ..i128::MIN);
+ | ^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:43:14
+ |
+LL | m!(0f32, ..f32::NEG_INFINITY);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:46:14
+ |
+LL | m!(0f64, ..f64::NEG_INFINITY);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:50:13
+ |
+LL | m!('a', ..'\u{0}');
+ | ^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:11:11
+ |
+LL | m!(0, ..u8::MIN);
+ | ^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11
+ |
+LL | m!(0, ..u16::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:17:11
+ |
+LL | m!(0, ..u32::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:20:11
+ |
+LL | m!(0, ..u64::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11
+ |
+LL | m!(0, ..u128::MIN);
+ | ^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11
+ |
+LL | m!(0, ..i8::MIN);
+ | ^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11
+ |
+LL | m!(0, ..i16::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:33:11
+ |
+LL | m!(0, ..i32::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:36:11
+ |
+LL | m!(0, ..i64::MIN);
+ | ^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:39:11
+ |
+LL | m!(0, ..i128::MIN);
+ | ^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:43:14
+ |
+LL | m!(0f32, ..f32::NEG_INFINITY);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:46:14
+ |
+LL | m!(0f64, ..f64::NEG_INFINITY);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/half-open-range-pats-thir-lower-empty.rs:50:13
+ |
+LL | m!('a', ..'\u{0}');
+ | ^^^^^^^^^
+
+error: aborting due to 26 previous errors
+
+For more information about this error, try `rustc --explain E0579`.
diff --git a/tests/ui/half-open-range-patterns/pat-tuple-4.rs b/tests/ui/half-open-range-patterns/pat-tuple-4.rs
new file mode 100644
index 000000000..11c4ab9c5
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/pat-tuple-4.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ const PAT: u8 = 1;
+
+ match 0 {
+ (.. PAT) => {}
+ _ => {}
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/pat-tuple-5.rs b/tests/ui/half-open-range-patterns/pat-tuple-5.rs
new file mode 100644
index 000000000..995ef03c8
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/pat-tuple-5.rs
@@ -0,0 +1,9 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ const PAT: u8 = 1;
+
+ match (0, 1) {
+ (PAT ..) => {} //~ ERROR mismatched types
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/pat-tuple-5.stderr b/tests/ui/half-open-range-patterns/pat-tuple-5.stderr
new file mode 100644
index 000000000..c60842638
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/pat-tuple-5.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/pat-tuple-5.rs:7:10
+ |
+LL | match (0, 1) {
+ | ------ this expression has type `({integer}, {integer})`
+LL | (PAT ..) => {}
+ | ^^^ expected tuple, found `u8`
+ |
+ = note: expected tuple `({integer}, {integer})`
+ found type `u8`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions0.rs b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs
new file mode 100644
index 000000000..acb7feac1
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions0.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![allow(incomplete_features)]
+#![feature(exclusive_range_pattern)]
+#![feature(inline_const_pat)]
+
+fn main() {
+ let mut if_lettable = vec![];
+ let mut first_or = vec![];
+ let mut or_two = vec![];
+ let mut range_from = vec![];
+ let mut bottom = vec![];
+
+ for x in -9 + 1..=(9 - 2) {
+ if let -1..=0 | 2..3 | 4 = x {
+ if_lettable.push(x)
+ }
+ match x {
+ 1 | -3..0 => first_or.push(x),
+ y @ (0..5 | 6) => or_two.push(y),
+ y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ y @ -5.. => range_from.push(y),
+ y @ ..-7 => assert_eq!(y, -8),
+ y => bottom.push(y),
+ }
+ }
+ assert_eq!(if_lettable, [-1, 0, 2, 4]);
+ assert_eq!(first_or, [-3, -2, -1, 1]);
+ assert_eq!(or_two, [0, 2, 3, 4, 6]);
+ assert_eq!(range_from, [-5, -4, 7]);
+ assert_eq!(bottom, [-7, -6]);
+}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
new file mode 100644
index 000000000..55353999b
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
@@ -0,0 +1,29 @@
+fn main() {
+ let mut if_lettable = Vec::<i32>::new();
+ let mut first_or = Vec::<i32>::new();
+ let mut or_two = Vec::<i32>::new();
+ let mut range_from = Vec::<i32>::new();
+ let mut bottom = Vec::<i32>::new();
+ let mut errors_only = Vec::<i32>::new();
+
+ for x in -9 + 1..=(9 - 2) {
+ if let n @ 2..3|4 = x {
+ //~^ error: variable `n` is not bound in all patterns
+ //~| exclusive range pattern syntax is experimental
+ errors_only.push(x);
+ } else if let 2..3 | 4 = x {
+ //~^ exclusive range pattern syntax is experimental
+ if_lettable.push(x);
+ }
+ match x as i32 {
+ 0..5+1 => errors_only.push(x),
+ //~^ error: expected one of `=>`, `if`, or `|`, found `+`
+ 1 | -3..0 => first_or.push(x),
+ y @ (0..5 | 6) => or_two.push(y),
+ y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ y @ -5.. => range_from.push(y),
+ y @ ..-7 => assert_eq!(y, -8),
+ y => bottom.push(y),
+ }
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
new file mode 100644
index 000000000..19ebcaf0f
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -0,0 +1,36 @@
+error: expected one of `=>`, `if`, or `|`, found `+`
+ --> $DIR/range_pat_interactions1.rs:19:17
+ |
+LL | 0..5+1 => errors_only.push(x),
+ | ^ expected one of `=>`, `if`, or `|`
+
+error[E0408]: variable `n` is not bound in all patterns
+ --> $DIR/range_pat_interactions1.rs:10:25
+ |
+LL | if let n @ 2..3|4 = x {
+ | - ^ pattern doesn't bind `n`
+ | |
+ | variable not in all patterns
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions1.rs:10:20
+ |
+LL | if let n @ 2..3|4 = x {
+ | ^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions1.rs:14:23
+ |
+LL | } else if let 2..3 | 4 = x {
+ | ^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0408, E0658.
+For more information about an error, try `rustc --explain E0408`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
new file mode 100644
index 000000000..4615ebd68
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
@@ -0,0 +1,21 @@
+fn main() {
+ let mut first_or = Vec::<i32>::new();
+ let mut or_two = Vec::<i32>::new();
+ let mut range_from = Vec::<i32>::new();
+ let mut bottom = Vec::<i32>::new();
+ let mut errors_only = Vec::<i32>::new();
+
+ for x in -9 + 1..=(9 - 2) {
+ match x as i32 {
+ 0..=(5+1) => errors_only.push(x),
+ //~^ error: inclusive range with no end
+ //~| error: expected one of `=>`, `if`, or `|`, found `(`
+ 1 | -3..0 => first_or.push(x),
+ y @ (0..5 | 6) => or_two.push(y),
+ y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ y @ -5.. => range_from.push(y),
+ y @ ..-7 => assert_eq!(y, -8),
+ y => bottom.push(y),
+ }
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
new file mode 100644
index 000000000..13a5542a4
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -0,0 +1,17 @@
+error[E0586]: inclusive range with no end
+ --> $DIR/range_pat_interactions2.rs:10:14
+ |
+LL | 0..=(5+1) => errors_only.push(x),
+ | ^^^ help: use `..` instead
+ |
+ = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found `(`
+ --> $DIR/range_pat_interactions2.rs:10:17
+ |
+LL | 0..=(5+1) => errors_only.push(x),
+ | ^ expected one of `=>`, `if`, or `|`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.rs b/tests/ui/half-open-range-patterns/range_pat_interactions3.rs
new file mode 100644
index 000000000..446ed45f9
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions3.rs
@@ -0,0 +1,23 @@
+fn main() {
+ let mut first_or = Vec::<i32>::new();
+ let mut or_two = Vec::<i32>::new();
+ let mut range_from = Vec::<i32>::new();
+ let mut bottom = Vec::<i32>::new();
+
+ for x in -9 + 1..=(9 - 2) {
+ match x as i32 {
+ 8.. => bottom.push(x),
+ 1 | -3..0 => first_or.push(x),
+ //~^ exclusive range pattern syntax is experimental
+ y @ (0..5 | 6) => or_two.push(y),
+ //~^ exclusive range pattern syntax is experimental
+ y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ //~^ inline-const in pattern position is experimental
+ //~| exclusive range pattern syntax is experimental
+ y @ -5.. => range_from.push(y),
+ y @ ..-7 => assert_eq!(y, -8),
+ //~^ exclusive range pattern syntax is experimental
+ y => bottom.push(y),
+ }
+ }
+}
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr
new file mode 100644
index 000000000..f7fda6775
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions3.stderr
@@ -0,0 +1,48 @@
+error[E0658]: inline-const in pattern position is experimental
+ --> $DIR/range_pat_interactions3.rs:14:20
+ |
+LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ | ^^^^^
+ |
+ = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+ = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions3.rs:10:17
+ |
+LL | 1 | -3..0 => first_or.push(x),
+ | ^^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions3.rs:12:18
+ |
+LL | y @ (0..5 | 6) => or_two.push(y),
+ | ^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions3.rs:14:17
+ |
+LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/range_pat_interactions3.rs:18:17
+ |
+LL | y @ ..-7 => assert_eq!(y, -8),
+ | ^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs
new file mode 100644
index 000000000..d54cbfbf4
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.rs
@@ -0,0 +1,16 @@
+#![feature(half_open_range_patterns_in_slices)]
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ let xs = [13, 1, 5, 2, 3, 1, 21, 8];
+ let [a, b, c, rest @ ..] = xs;
+ // Consider the following example:
+ assert!(a == 13 && b == 1 && c == 5 && rest.len() == 5);
+
+ // What if we wanted to pull this apart without individually binding a, b, and c?
+ let [first_three @ ..3, rest @ 2..] = xs;
+ //~^ pattern requires 2 elements but array has 8
+ // This is somewhat unintuitive and makes slice patterns exceedingly verbose.
+ // We want to stabilize half-open RangeFrom (`X..`) patterns
+ // but without banning us from using them for a more efficient slice pattern syntax.
+}
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr
new file mode 100644
index 000000000..ec3472a50
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem0.stderr
@@ -0,0 +1,9 @@
+error[E0527]: pattern requires 2 elements but array has 8
+ --> $DIR/slice_pattern_syntax_problem0.rs:11:9
+ |
+LL | let [first_three @ ..3, rest @ 2..] = xs;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 8 elements
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0527`.
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs
new file mode 100644
index 000000000..c37af75b8
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs
@@ -0,0 +1,8 @@
+// Instead of allowing the previous case, maintain the feature gate for slice patterns for now.
+fn main() {
+ let xs = [13, 1, 5, 2, 3, 1, 21, 8];
+ let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ //~^ `X..` patterns in slices are experimental
+ //~| exclusive range pattern syntax is experimental
+ //~| exclusive range pattern syntax is experimental
+}
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
new file mode 100644
index 000000000..3bca554b1
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
@@ -0,0 +1,30 @@
+error[E0658]: `X..` patterns in slices are experimental
+ --> $DIR/slice_pattern_syntax_problem1.rs:4:10
+ |
+LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ | ^^^^^^^
+ |
+ = note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
+ = help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/slice_pattern_syntax_problem1.rs:4:23
+ |
+LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ | ^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0658]: exclusive range pattern syntax is experimental
+ --> $DIR/slice_pattern_syntax_problem1.rs:4:32
+ |
+LL | let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+ | ^^^^
+ |
+ = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+ = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs
new file mode 100644
index 000000000..6e7df3094
--- /dev/null
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem2.rs
@@ -0,0 +1,10 @@
+// run-pass
+
+fn main() {
+ let xs = [13, 1, 5, 2, 3, 1, 21, 8];
+ if let [3..=14, ..] = xs {
+ /* this variant must pass for now, unfortunately.
+ * This test is included here to help inform a future plan for these.
+ */
+ };
+}