about summary refs log tree commit diff
path: root/src/test/ui/exhaustive_integer_patterns.rs
blob: 2570bc8a56078be796593a113e2d11ef9123ba81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#![feature(precise_pointer_size_matching)]
#![feature(exclusive_range_pattern)]

#![deny(unreachable_patterns)]

use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128};

fn main() {
    let x: u8 = 0;

    // A single range covering the entire domain.
    match x {
        0 ..= 255 => {} // ok
    }

    // A combination of ranges and values.
    // These are currently allowed to be overlapping.
    match x {
        0 ..= 32 => {}
        33 => {}
        34 .. 128 => {}
        100 ..= 200 => {}
        200 => {} //~ ERROR unreachable pattern
        201 ..= 255 => {}
    }

    // An incomplete set of values.
    match x { //~ ERROR non-exhaustive patterns
        0 .. 128 => {}
    }

    // A more incomplete set of values.
    match x { //~ ERROR non-exhaustive patterns
        0 ..= 10 => {}
        20 ..= 30 => {}
        35 => {}
        70 .. 255 => {}
    }

    let x: i8 = 0;
    match x { //~ ERROR non-exhaustive patterns
        -7 => {}
        -5..=120 => {}
        -2..=20 => {} //~ ERROR unreachable pattern
        125 => {}
    }

    // Let's test other types too!
    let c: char = '\u{0}';
    match c {
        '\u{0}' ..= char::MAX => {} // ok
    }

    // We can actually get away with just covering the
    // following two ranges, which correspond to all
    // valid Unicode Scalar Values.
    match c {
        '\u{0000}' ..= '\u{D7FF}' => {}
        '\u{E000}' ..= '\u{10_FFFF}' => {}
    }

    match 0u16 {
        0 ..= u16::MAX => {} // ok
    }

    match 0u32 {
        0 ..= u32::MAX => {} // ok
    }

    match 0u64 {
        0 ..= u64::MAX => {} // ok
    }

    match 0u128 {
        0 ..= u128::MAX => {} // ok
    }

    match 0i8 {
        -128 ..= 127 => {} // ok
    }

    match 0i8 { //~ ERROR non-exhaustive patterns
        -127 ..= 127 => {}
    }

    match 0i16 {
        i16::MIN ..= i16::MAX => {} // ok
    }

    match 0i16 { //~ ERROR non-exhaustive patterns
        i16::MIN ..= -1 => {}
        1 ..= i16::MAX => {}
    }

    match 0i32 {
        i32::MIN ..= i32::MAX => {} // ok
    }

    match 0i64 {
        i64::MIN ..= i64::MAX => {} // ok
    }

    match 0i128 {
        i128::MIN ..= i128::MAX => {} // ok
    }

    // Make sure that guards don't factor into the exhaustiveness checks.
    match 0u8 { //~ ERROR non-exhaustive patterns
        0 .. 128 => {}
        128 ..= 255 if true => {}
    }

    match 0u8 {
        0 .. 128 => {}
        128 ..= 255 if false => {}
        128 ..= 255 => {} // ok, because previous arm was guarded
    }

    // Now things start getting a bit more interesting. Testing products!
    match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
        (1, _) => {}
        (_, None) => {}
    }

    match (0u8, true) { //~ ERROR non-exhaustive patterns
        (0 ..= 125, false) => {}
        (128 ..= 255, false) => {}
        (0 ..= 255, true) => {}
    }

    match (0u8, true) { // ok
        (0 ..= 125, false) => {}
        (128 ..= 255, false) => {}
        (0 ..= 255, true) => {}
        (125 .. 128, false) => {}
    }

    match 0u8 { // ok
        0 .. 2 => {}
        1 ..= 2 => {}
        _ => {}
    }

    const LIM: u128 = u128::MAX - 1;
    match 0u128 { //~ ERROR non-exhaustive patterns
        0 ..= LIM => {}
    }

    match 0u128 { //~ ERROR non-exhaustive patterns
        0 ..= 4 => {}
    }

    match 0u128 { //~ ERROR non-exhaustive patterns
        4 ..= u128::MAX => {}
    }
}