Skip to content

Commit e018268

Browse files
committed
Add precise_pointer_size_matching feature
1 parent f1f6d87 commit e018268

File tree

6 files changed

+42
-2
lines changed

6 files changed

+42
-2
lines changed

src/librustc/ty/sty.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
17801780
}
17811781
}
17821782

1783+
pub fn is_pointer_sized(&self) -> bool {
1784+
match self.sty {
1785+
Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
1786+
_ => false,
1787+
}
1788+
}
1789+
17831790
pub fn is_machine(&self) -> bool {
17841791
match self.sty {
17851792
Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,

src/librustc_mir/hair/pattern/_match.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,8 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
11291129

11301130
// For privately empty and non-exhaustive enums, we work as if there were an "extra"
11311131
// `_` constructor for the type, so we can never match over all constructors.
1132-
let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive;
1132+
let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive ||
1133+
(pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching);
11331134

11341135
if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive {
11351136
split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
@@ -1436,7 +1437,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Construct
14361437
_ => return false,
14371438
};
14381439
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
1439-
true
1440+
!ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching
14401441
} else {
14411442
false
14421443
}

src/libsyntax/feature_gate.rs

+2
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ declare_features! (
439439
// 'a: { break 'a; }
440440
(active, label_break_value, "1.28.0", Some(48594), None),
441441

442+
// Exhaustive pattern matching on `usize` and `isize`.
443+
(active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
442444

443445
// #[doc(keyword = "...")]
444446
(active, doc_keyword, "1.28.0", Some(51315), None),

src/test/ui/exhaustive_integer_patterns.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(precise_pointer_size_matching)]
1112
#![feature(exclusive_range_pattern)]
1213

1314
#![deny(unreachable_patterns)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(exclusive_range_pattern)]
2+
3+
use std::usize::MAX;
4+
5+
fn main() {
6+
match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
7+
0..=MAX => {}
8+
}
9+
10+
match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
11+
1..=20 => {}
12+
-5..3 => {}
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0004]: non-exhaustive patterns: `_` not covered
2+
--> $DIR/feature-gate-precise_pointer_size_matching.rs:6:11
3+
|
4+
LL | match 0usize { //~ERROR non-exhaustive patterns: `_` not covered
5+
| ^^^^^^ pattern `_` not covered
6+
7+
error[E0004]: non-exhaustive patterns: `_` not covered
8+
--> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11
9+
|
10+
LL | match 0isize { //~ERROR non-exhaustive patterns: `_` not covered
11+
| ^^^^^^ pattern `_` not covered
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0004`.

0 commit comments

Comments
 (0)