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