From e018268ffad0e3d2704705cb3337b6195b5cba08 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 30 Nov 2018 00:44:33 +0000 Subject: [PATCH] Add precise_pointer_size_matching feature --- src/librustc/ty/sty.rs | 7 +++++++ src/librustc_mir/hair/pattern/_match.rs | 5 +++-- src/libsyntax/feature_gate.rs | 2 ++ src/test/ui/exhaustive_integer_patterns.rs | 1 + .../feature-gate-precise_pointer_size_matching.rs | 14 ++++++++++++++ ...ture-gate-precise_pointer_size_matching.stderr | 15 +++++++++++++++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs create mode 100644 src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index a18e3a275467d..fbc986965742f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1780,6 +1780,13 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + pub fn is_pointer_sized(&self) -> bool { + match self.sty { + Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true, + _ => false, + } + } + pub fn is_machine(&self) -> bool { match self.sty { Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 82e368198f245..a2fbfd70a6540 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -1129,7 +1129,8 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, // For privately empty and non-exhaustive enums, we work as if there were an "extra" // `_` constructor for the type, so we can never match over all constructors. - let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive; + let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive || + (pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching); if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive { 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 _ => return false, }; if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty { - true + !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching } else { false } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 53faf04f27891..1567932266313 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -439,6 +439,8 @@ declare_features! ( // 'a: { break 'a; } (active, label_break_value, "1.28.0", Some(48594), None), + // Exhaustive pattern matching on `usize` and `isize`. + (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), // #[doc(keyword = "...")] (active, doc_keyword, "1.28.0", Some(51315), None), diff --git a/src/test/ui/exhaustive_integer_patterns.rs b/src/test/ui/exhaustive_integer_patterns.rs index cddb301dbdf23..ad955fbe05d46 100644 --- a/src/test/ui/exhaustive_integer_patterns.rs +++ b/src/test/ui/exhaustive_integer_patterns.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(precise_pointer_size_matching)] #![feature(exclusive_range_pattern)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs new file mode 100644 index 0000000000000..1208552d25637 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs @@ -0,0 +1,14 @@ +#![feature(exclusive_range_pattern)] + +use std::usize::MAX; + +fn main() { + match 0usize { //~ERROR non-exhaustive patterns: `_` not covered + 0..=MAX => {} + } + + match 0isize { //~ERROR non-exhaustive patterns: `_` not covered + 1..=20 => {} + -5..3 => {} + } +} diff --git a/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr new file mode 100644 index 0000000000000..5806f6f039157 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-precise_pointer_size_matching.stderr @@ -0,0 +1,15 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/feature-gate-precise_pointer_size_matching.rs:6:11 + | +LL | match 0usize { //~ERROR non-exhaustive patterns: `_` not covered + | ^^^^^^ pattern `_` not covered + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/feature-gate-precise_pointer_size_matching.rs:10:11 + | +LL | match 0isize { //~ERROR non-exhaustive patterns: `_` not covered + | ^^^^^^ pattern `_` not covered + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`.