Skip to content

Commit ecfdeeb

Browse files
committed
use MIN/MAX constant names in integer pattern coverage messages
While many programmers may intuitively appreciate the significance of magic numbers like −2147483648, Rust is about empowering everyone to build reliable and efficient software! It's a bit more legible to print the constant names. The `max_as_i128`, &c. methods strewn in libsyntax are a bit unsightly, but I fear this is really the most natural way to solve the problem. Resolves rust-lang#56393.
1 parent 2d3e909 commit ecfdeeb

13 files changed

+89
-44
lines changed

Diff for: src/librustc/mir/mod.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -2624,7 +2624,13 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const<'_>) -> fmt::Resu
26242624
Bool if bits == 1 => return write!(f, "true"),
26252625
Float(ast::FloatTy::F32) => return write!(f, "{}f32", Single::from_bits(bits)),
26262626
Float(ast::FloatTy::F64) => return write!(f, "{}f64", Double::from_bits(bits)),
2627-
Uint(ui) => return write!(f, "{:?}{}", bits, ui),
2627+
Uint(ui) => {
2628+
return match bits {
2629+
// writing 0 as uX::MIN wouldn't clarify
2630+
n if n == ui.max_as_u128() => write!(f, "::std::{}::MAX", ui),
2631+
_ => write!(f, "{:?}{}", bits, ui)
2632+
}
2633+
}
26282634
Int(i) => {
26292635
let bit_width = ty::tls::with(|tcx| {
26302636
let ty = tcx.lift_to_global(&ty).unwrap();
@@ -2634,7 +2640,12 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const<'_>) -> fmt::Resu
26342640
.bits()
26352641
});
26362642
let shift = 128 - bit_width;
2637-
return write!(f, "{:?}{}", ((bits as i128) << shift) >> shift, i);
2643+
let n = ((bits as i128) << shift) >> shift;
2644+
return match n {
2645+
m if m == i.min_as_i128() => write!(f, "::std::{}::MIN", i),
2646+
m if m == i.max_as_i128() => write!(f, "::std::{}::MAX", i),
2647+
_ => write!(f, "{:?}{}", n, i)
2648+
}
26382649
}
26392650
Char => return write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap()),
26402651
_ => {}

Diff for: src/libsyntax/ast.rs

+34
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,29 @@ impl IntTy {
14581458
IntTy::I128 => 128,
14591459
})
14601460
}
1461+
1462+
pub fn min_as_i128(&self) -> i128 {
1463+
match *self {
1464+
IntTy::Isize => ::std::isize::MIN as i128,
1465+
IntTy::I8 => ::std::i8::MIN as i128,
1466+
IntTy::I16 => ::std::i16::MIN as i128,
1467+
IntTy::I32 => ::std::i32::MIN as i128,
1468+
IntTy::I64 => ::std::i64::MIN as i128,
1469+
IntTy::I128 => ::std::i128::MIN,
1470+
}
1471+
}
1472+
1473+
pub fn max_as_i128(&self) -> i128 {
1474+
match *self {
1475+
IntTy::Isize => ::std::isize::MAX as i128,
1476+
IntTy::I8 => ::std::i8::MAX as i128,
1477+
IntTy::I16 => ::std::i16::MAX as i128,
1478+
IntTy::I32 => ::std::i32::MAX as i128,
1479+
IntTy::I64 => ::std::i64::MAX as i128,
1480+
IntTy::I128 => ::std::i128::MAX,
1481+
}
1482+
}
1483+
14611484
}
14621485

14631486
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
@@ -1496,6 +1519,17 @@ impl UintTy {
14961519
UintTy::U128 => 128,
14971520
})
14981521
}
1522+
1523+
pub fn max_as_u128(&self) -> u128 {
1524+
match *self {
1525+
UintTy::Usize => ::std::usize::MAX as u128,
1526+
UintTy::U8 => ::std::u8::MAX as u128,
1527+
UintTy::U16 => ::std::u16::MAX as u128,
1528+
UintTy::U32 => ::std::u32::MAX as u128,
1529+
UintTy::U64 => ::std::u64::MAX as u128,
1530+
UintTy::U128 => ::std::u128::MAX,
1531+
}
1532+
}
14991533
}
15001534

15011535
impl fmt::Debug for UintTy {

Diff for: src/test/ui/consts/const-match-check.eval1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
1+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
22
--> $DIR/const-match-check.rs:35:15
33
|
44
LL | A = { let 0 = 0; 0 },
5-
| ^ pattern `-2147483648i32..=-1i32` not covered
5+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
66

77
error: aborting due to previous error
88

Diff for: src/test/ui/consts/const-match-check.eval2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
1+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
22
--> $DIR/const-match-check.rs:41:24
33
|
44
LL | let x: [i32; { let 0 = 0; 0 }] = [];
5-
| ^ pattern `-2147483648i32..=-1i32` not covered
5+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
66

77
error: aborting due to previous error
88

Diff for: src/test/ui/consts/const-match-check.matchck.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
1+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
22
--> $DIR/const-match-check.rs:14:22
33
|
44
LL | const X: i32 = { let 0 = 0; 0 };
5-
| ^ pattern `-2147483648i32..=-1i32` not covered
5+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
66

7-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
7+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
88
--> $DIR/const-match-check.rs:18:23
99
|
1010
LL | static Y: i32 = { let 0 = 0; 0 };
11-
| ^ pattern `-2147483648i32..=-1i32` not covered
11+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
1212

13-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
13+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
1414
--> $DIR/const-match-check.rs:23:26
1515
|
1616
LL | const X: i32 = { let 0 = 0; 0 };
17-
| ^ pattern `-2147483648i32..=-1i32` not covered
17+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
1818

19-
error[E0005]: refutable pattern in local binding: `-2147483648i32..=-1i32` not covered
19+
error[E0005]: refutable pattern in local binding: `::std::i32::MIN..=-1i32` not covered
2020
--> $DIR/const-match-check.rs:29:26
2121
|
2222
LL | const X: i32 = { let 0 = 0; 0 };
23-
| ^ pattern `-2147483648i32..=-1i32` not covered
23+
| ^ pattern `::std::i32::MIN..=-1i32` not covered
2424

2525
error: aborting due to 4 previous errors
2626

Diff for: src/test/ui/exhaustive_integer_patterns.stderr

+14-14
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ note: lint level defined here
1010
LL | #![deny(unreachable_patterns)]
1111
| ^^^^^^^^^^^^^^^^^^^^
1212

13-
error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
13+
error[E0004]: non-exhaustive patterns: `128u8..=::std::u8::MAX` not covered
1414
--> $DIR/exhaustive_integer_patterns.rs:38:11
1515
|
1616
LL | match x { //~ ERROR non-exhaustive patterns
17-
| ^ pattern `128u8..=255u8` not covered
17+
| ^ pattern `128u8..=::std::u8::MAX` not covered
1818

1919
error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered
2020
--> $DIR/exhaustive_integer_patterns.rs:43:11
@@ -28,53 +28,53 @@ error: unreachable pattern
2828
LL | -2..=20 => {} //~ ERROR unreachable pattern
2929
| ^^^^^^^
3030

31-
error[E0004]: non-exhaustive patterns: `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
31+
error[E0004]: non-exhaustive patterns: `::std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
3232
--> $DIR/exhaustive_integer_patterns.rs:51:11
3333
|
3434
LL | match x { //~ ERROR non-exhaustive patterns
35-
| ^ patterns `-128i8..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
35+
| ^ patterns `::std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered
3636

37-
error[E0004]: non-exhaustive patterns: `-128i8` not covered
37+
error[E0004]: non-exhaustive patterns: `::std::i8::MIN` not covered
3838
--> $DIR/exhaustive_integer_patterns.rs:92:11
3939
|
4040
LL | match 0i8 { //~ ERROR non-exhaustive patterns
41-
| ^^^ pattern `-128i8` not covered
41+
| ^^^ pattern `::std::i8::MIN` not covered
4242

4343
error[E0004]: non-exhaustive patterns: `0i16` not covered
4444
--> $DIR/exhaustive_integer_patterns.rs:100:11
4545
|
4646
LL | match 0i16 { //~ ERROR non-exhaustive patterns
4747
| ^^^^ pattern `0i16` not covered
4848

49-
error[E0004]: non-exhaustive patterns: `128u8..=255u8` not covered
49+
error[E0004]: non-exhaustive patterns: `128u8..=::std::u8::MAX` not covered
5050
--> $DIR/exhaustive_integer_patterns.rs:118:11
5151
|
5252
LL | match 0u8 { //~ ERROR non-exhaustive patterns
53-
| ^^^ pattern `128u8..=255u8` not covered
53+
| ^^^ pattern `128u8..=::std::u8::MAX` not covered
5454

55-
error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
55+
error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=::std::u8::MAX, Some(_))` not covered
5656
--> $DIR/exhaustive_integer_patterns.rs:130:11
5757
|
5858
LL | match (0u8, Some(())) { //~ ERROR non-exhaustive patterns
59-
| ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=255u8, Some(_))` not covered
59+
| ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=::std::u8::MAX, Some(_))` not covered
6060

6161
error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered
6262
--> $DIR/exhaustive_integer_patterns.rs:135:11
6363
|
6464
LL | match (0u8, true) { //~ ERROR non-exhaustive patterns
6565
| ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered
6666

67-
error[E0004]: non-exhaustive patterns: `340282366920938463463374607431768211455u128` not covered
67+
error[E0004]: non-exhaustive patterns: `::std::u128::MAX` not covered
6868
--> $DIR/exhaustive_integer_patterns.rs:155:11
6969
|
7070
LL | match 0u128 { //~ ERROR non-exhaustive patterns
71-
| ^^^^^ pattern `340282366920938463463374607431768211455u128` not covered
71+
| ^^^^^ pattern `::std::u128::MAX` not covered
7272

73-
error[E0004]: non-exhaustive patterns: `5u128..=340282366920938463463374607431768211455u128` not covered
73+
error[E0004]: non-exhaustive patterns: `5u128..=::std::u128::MAX` not covered
7474
--> $DIR/exhaustive_integer_patterns.rs:159:11
7575
|
7676
LL | match 0u128 { //~ ERROR non-exhaustive patterns
77-
| ^^^^^ pattern `5u128..=340282366920938463463374607431768211455u128` not covered
77+
| ^^^^^ pattern `5u128..=::std::u128::MAX` not covered
7878

7979
error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered
8080
--> $DIR/exhaustive_integer_patterns.rs:163:11

Diff for: src/test/ui/for/for-loop-refutable-pattern-error-message.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0005]: refutable pattern in `for` loop binding: `&-2147483648i32..=0i32` not covered
1+
error[E0005]: refutable pattern in `for` loop binding: `&::std::i32::MIN..=0i32` not covered
22
--> $DIR/for-loop-refutable-pattern-error-message.rs:12:9
33
|
44
LL | for &1 in [1].iter() {} //~ ERROR refutable pattern in `for` loop binding
5-
| ^^ pattern `&-2147483648i32..=0i32` not covered
5+
| ^^ pattern `&::std::i32::MIN..=0i32` not covered
66

77
error: aborting due to previous error
88

Diff for: src/test/ui/match/match-non-exhaustive.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0004]: non-exhaustive patterns: `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
1+
error[E0004]: non-exhaustive patterns: `::std::i32::MIN..=0i32` and `2i32..=::std::i32::MAX` not covered
22
--> $DIR/match-non-exhaustive.rs:12:11
33
|
44
LL | match 0 { 1 => () } //~ ERROR non-exhaustive patterns
5-
| ^ patterns `-2147483648i32..=0i32` and `2i32..=2147483647i32` not covered
5+
| ^ patterns `::std::i32::MIN..=0i32` and `2i32..=::std::i32::MAX` not covered
66

77
error[E0004]: non-exhaustive patterns: `_` not covered
88
--> $DIR/match-non-exhaustive.rs:13:11

Diff for: src/test/ui/non-exhaustive/non-exhaustive-match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ fn main() {
2222
match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
2323
None => {}
2424
}
25-
match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
26-
// and `(_, _, 5i32..=2147483647i32)` not covered
25+
match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, ::std::i32::MIN..=3i32)`
26+
// and `(_, _, 5i32..=::std::i32::MAX)` not covered
2727
(_, _, 4) => {}
2828
}
2929
match (t::a, t::a) { //~ ERROR non-exhaustive patterns: `(a, a)` not covered

Diff for: src/test/ui/non-exhaustive/non-exhaustive-match.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ error[E0004]: non-exhaustive patterns: `Some(_)` not covered
1616
LL | match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered
1717
| ^^^^^^^^ pattern `Some(_)` not covered
1818

19-
error[E0004]: non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
19+
error[E0004]: non-exhaustive patterns: `(_, _, ::std::i32::MIN..=3i32)` and `(_, _, 5i32..=::std::i32::MAX)` not covered
2020
--> $DIR/non-exhaustive-match.rs:25:11
2121
|
22-
LL | match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, -2147483648i32..=3i32)`
23-
| ^^^^^^^^^ patterns `(_, _, -2147483648i32..=3i32)` and `(_, _, 5i32..=2147483647i32)` not covered
22+
LL | match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, ::std::i32::MIN..=3i32)`
23+
| ^^^^^^^^^ patterns `(_, _, ::std::i32::MIN..=3i32)` and `(_, _, 5i32..=::std::i32::MAX)` not covered
2424

2525
error[E0004]: non-exhaustive patterns: `(a, a)` not covered
2626
--> $DIR/non-exhaustive-match.rs:29:11

Diff for: src/test/ui/precise_pointer_size_matching.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0004]: non-exhaustive patterns: `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
1+
error[E0004]: non-exhaustive patterns: `::std::isize::MIN..=-6isize` and `21isize..=::std::isize::MAX` not covered
22
--> $DIR/precise_pointer_size_matching.rs:24:11
33
|
44
LL | match 0isize { //~ ERROR non-exhaustive patterns
5-
| ^^^^^^ patterns `$ISIZE_MIN..=-6isize` and `21isize..=$ISIZE_MAX` not covered
5+
| ^^^^^^ patterns `::std::isize::MIN..=-6isize` and `21isize..=::std::isize::MAX` not covered
66

7-
error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=$USIZE_MAX` not covered
7+
error[E0004]: non-exhaustive patterns: `0usize` and `21usize..=::std::usize::MAX` not covered
88
--> $DIR/precise_pointer_size_matching.rs:29:11
99
|
1010
LL | match 0usize { //~ ERROR non-exhaustive patterns
11-
| ^^^^^^ patterns `0usize` and `21usize..=$USIZE_MAX` not covered
11+
| ^^^^^^ patterns `0usize` and `21usize..=::std::usize::MAX` not covered
1212

1313
error: aborting due to 2 previous errors
1414

Diff for: src/test/ui/refutable-pattern-errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
1414

1515
fn main() {
1616
let (1, (Some(1), 2..=3)) = (1, (None, 2));
17-
//~^ ERROR refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
17+
//~^ ERROR refutable pattern in local binding: `(::std::i32::MIN..=0i32, _)` not covered
1818
}

Diff for: src/test/ui/refutable-pattern-errors.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0005]: refutable pattern in function argument: `(_, _)` not covered
44
LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
55
| ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
66

7-
error[E0005]: refutable pattern in local binding: `(-2147483648i32..=0i32, _)` not covered
7+
error[E0005]: refutable pattern in local binding: `(::std::i32::MIN..=0i32, _)` not covered
88
--> $DIR/refutable-pattern-errors.rs:16:9
99
|
1010
LL | let (1, (Some(1), 2..=3)) = (1, (None, 2));
11-
| ^^^^^^^^^^^^^^^^^^^^^ pattern `(-2147483648i32..=0i32, _)` not covered
11+
| ^^^^^^^^^^^^^^^^^^^^^ pattern `(::std::i32::MIN..=0i32, _)` not covered
1212

1313
error: aborting due to 2 previous errors
1414

0 commit comments

Comments
 (0)