]> git.proxmox.com Git - rustc.git/blob - src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / src / test / ui / pattern / usefulness / exhaustive_integer_patterns.rs
1 #![feature(precise_pointer_size_matching)]
2 #![feature(exclusive_range_pattern)]
3 #![deny(unreachable_patterns)]
4 #![deny(overlapping_patterns)]
5
6 use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};
7
8 fn main() {
9 let x: u8 = 0;
10
11 // A single range covering the entire domain.
12 match x {
13 0 ..= 255 => {} // ok
14 }
15
16 // A combination of ranges and values.
17 // These are currently allowed to be overlapping.
18 match x {
19 0 ..= 32 => {}
20 33 => {}
21 34 .. 128 => {}
22 100 ..= 200 => {}
23 200 => {} //~ ERROR unreachable pattern
24 201 ..= 255 => {}
25 }
26
27 // An incomplete set of values.
28 match x { //~ ERROR non-exhaustive patterns
29 0 .. 128 => {}
30 }
31
32 // A more incomplete set of values.
33 match x { //~ ERROR non-exhaustive patterns
34 0 ..= 10 => {}
35 20 ..= 30 => {}
36 35 => {}
37 70 .. 255 => {}
38 }
39
40 let x: i8 = 0;
41 match x { //~ ERROR non-exhaustive patterns
42 -7 => {}
43 -5..=120 => {}
44 -2..=20 => {}
45 //~^ ERROR unreachable pattern
46 125 => {}
47 }
48
49 // Let's test other types too!
50 let c: char = '\u{0}';
51 match c {
52 '\u{0}' ..= char::MAX => {} // ok
53 }
54
55 // We can actually get away with just covering the
56 // following two ranges, which correspond to all
57 // valid Unicode Scalar Values.
58 match c {
59 '\u{0000}' ..= '\u{D7FF}' => {}
60 '\u{E000}' ..= '\u{10_FFFF}' => {}
61 }
62
63 match 0u16 {
64 0 ..= u16::MAX => {} // ok
65 }
66
67 match 0u32 {
68 0 ..= u32::MAX => {} // ok
69 }
70
71 match 0u64 {
72 0 ..= u64::MAX => {} // ok
73 }
74
75 match 0u128 {
76 0 ..= u128::MAX => {} // ok
77 }
78
79 match 0i8 {
80 -128 ..= 127 => {} // ok
81 }
82
83 match 0i8 { //~ ERROR non-exhaustive patterns
84 -127 ..= 127 => {}
85 }
86
87 match 0i16 {
88 i16::MIN ..= i16::MAX => {} // ok
89 }
90
91 match 0i16 { //~ ERROR non-exhaustive patterns
92 i16::MIN ..= -1 => {}
93 1 ..= i16::MAX => {}
94 }
95
96 match 0i32 {
97 i32::MIN ..= i32::MAX => {} // ok
98 }
99
100 match 0i64 {
101 i64::MIN ..= i64::MAX => {} // ok
102 }
103
104 match 0i128 {
105 i128::MIN ..= i128::MAX => {} // ok
106 }
107
108 // Make sure that guards don't factor into the exhaustiveness checks.
109 match 0u8 { //~ ERROR non-exhaustive patterns
110 0 .. 128 => {}
111 128 ..= 255 if true => {}
112 }
113
114 match 0u8 {
115 0 .. 128 => {}
116 128 ..= 255 if false => {}
117 128 ..= 255 => {} // ok, because previous arm was guarded
118 }
119
120 // Now things start getting a bit more interesting. Testing products!
121 match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
122 (1, _) => {}
123 (_, None) => {}
124 }
125
126 match (0u8, true) { //~ ERROR non-exhaustive patterns
127 (0 ..= 125, false) => {}
128 (128 ..= 255, false) => {}
129 (0 ..= 255, true) => {}
130 }
131
132 match (0u8, true) { // ok
133 (0 ..= 125, false) => {}
134 (128 ..= 255, false) => {}
135 (0 ..= 255, true) => {}
136 (125 .. 128, false) => {}
137 }
138
139 match 0u8 {
140 0 .. 2 => {}
141 1 ..= 2 => {} //~ ERROR multiple patterns covering the same range
142 _ => {}
143 }
144
145 const LIM: u128 = u128::MAX - 1;
146 match 0u128 { //~ ERROR non-exhaustive patterns
147 0 ..= LIM => {}
148 }
149
150 match 0u128 { //~ ERROR non-exhaustive patterns
151 0 ..= 4 => {}
152 }
153
154 match 0u128 { //~ ERROR non-exhaustive patterns
155 4 ..= u128::MAX => {}
156 }
157
158 const FOO: i32 = 42;
159 const BAR: &i32 = &42;
160 match &0 {
161 &42 => {}
162 &FOO => {} //~ ERROR unreachable pattern
163 BAR => {} //~ ERROR unreachable pattern
164 _ => {}
165 }
166
167 // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933
168 match &0 {
169 BAR => {} // ok
170 _ => {}
171 }
172 }