Stabilise exhaustive_integer_patterns
This commit is contained in:
parent
3dde9e1322
commit
f1f6d87eab
3 changed files with 19 additions and 23 deletions
|
@ -622,7 +622,6 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
-> Vec<Constructor<'tcx>>
|
||||
{
|
||||
debug!("all_constructors({:?})", pcx.ty);
|
||||
let exhaustive_integer_patterns = cx.tcx.features().exhaustive_integer_patterns;
|
||||
let ctors = match pcx.ty.sty {
|
||||
ty::Bool => {
|
||||
[true, false].iter().map(|&b| {
|
||||
|
@ -652,7 +651,7 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
.map(|v| Variant(v.did))
|
||||
.collect()
|
||||
}
|
||||
ty::Char if exhaustive_integer_patterns => {
|
||||
ty::Char => {
|
||||
vec![
|
||||
// The valid Unicode Scalar Value ranges.
|
||||
ConstantRange('\u{0000}' as u128,
|
||||
|
@ -667,14 +666,14 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
),
|
||||
]
|
||||
}
|
||||
ty::Int(ity) if exhaustive_integer_patterns => {
|
||||
ty::Int(ity) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
|
||||
let min = 1u128 << (bits - 1);
|
||||
let max = (1u128 << (bits - 1)) - 1;
|
||||
vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
|
||||
}
|
||||
ty::Uint(uty) if exhaustive_integer_patterns => {
|
||||
ty::Uint(uty) => {
|
||||
// FIXME(49937): refactor these bit manipulations into interpret.
|
||||
let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
|
||||
let max = !0u128 >> (128 - bits);
|
||||
|
@ -971,12 +970,10 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
|
|||
// If a constructor appears in a `match` arm, we can
|
||||
// eliminate it straight away.
|
||||
refined_ctors = vec![]
|
||||
} else if tcx.features().exhaustive_integer_patterns {
|
||||
if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
|
||||
// Refine the required constructors for the type by subtracting
|
||||
// the range defined by the current constructor pattern.
|
||||
refined_ctors = interval.subtract_from(tcx, refined_ctors);
|
||||
}
|
||||
} else if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
|
||||
// Refine the required constructors for the type by subtracting
|
||||
// the range defined by the current constructor pattern.
|
||||
refined_ctors = interval.subtract_from(tcx, refined_ctors);
|
||||
}
|
||||
|
||||
// If the constructor patterns that have been considered so far
|
||||
|
@ -1433,17 +1430,16 @@ fn slice_pat_covered_by_constructor<'tcx>(
|
|||
// Whether to evaluate a constructor using exhaustive integer matching. This is true if the
|
||||
// constructor is a range or constant with an integer type.
|
||||
fn should_treat_range_exhaustively(tcx: TyCtxt<'_, 'tcx, 'tcx>, ctor: &Constructor<'tcx>) -> bool {
|
||||
if tcx.features().exhaustive_integer_patterns {
|
||||
let ty = match ctor {
|
||||
ConstantValue(value) => value.ty,
|
||||
ConstantRange(_, _, ty, _) => ty,
|
||||
_ => return false,
|
||||
};
|
||||
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
|
||||
return true;
|
||||
}
|
||||
let ty = match ctor {
|
||||
ConstantValue(value) => value.ty,
|
||||
ConstantRange(_, _, ty, _) => ty,
|
||||
_ => return false,
|
||||
};
|
||||
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// For exhaustive integer matching, some constructors are grouped within other constructors
|
||||
|
|
|
@ -439,8 +439,6 @@ declare_features! (
|
|||
// 'a: { break 'a; }
|
||||
(active, label_break_value, "1.28.0", Some(48594), None),
|
||||
|
||||
// Integer match exhaustiveness checking
|
||||
(active, exhaustive_integer_patterns, "1.30.0", Some(50907), None),
|
||||
|
||||
// #[doc(keyword = "...")]
|
||||
(active, doc_keyword, "1.28.0", Some(51315), None),
|
||||
|
@ -686,6 +684,8 @@ declare_features! (
|
|||
(accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
|
||||
// Allows use of the :literal macro fragment specifier (RFC 1576)
|
||||
(accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
|
||||
// Integer match exhaustiveness checking (RFC 2591)
|
||||
(accepted, exhaustive_integer_patterns, "1.32.0", Some(50907), None),
|
||||
// Use `?` as the Kleene "at most one" operator
|
||||
(accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
|
||||
);
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(exhaustive_integer_patterns)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
|
||||
#![deny(unreachable_patterns)]
|
||||
|
||||
use std::{char, usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128};
|
||||
|
|
Loading…
Add table
Reference in a new issue