Use usize for slice arity
This commit is contained in:
parent
3175409682
commit
035c5213ae
@ -389,17 +389,17 @@ fn iter<'a>(&'a self) -> impl Iterator<Item = IntRange> + Captures<'a> {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
enum SliceKind {
|
enum SliceKind {
|
||||||
/// Patterns of length `n` (`[x, y]`).
|
/// Patterns of length `n` (`[x, y]`).
|
||||||
FixedLen(u64),
|
FixedLen(usize),
|
||||||
/// Patterns using the `..` notation (`[x, .., y]`).
|
/// Patterns using the `..` notation (`[x, .., y]`).
|
||||||
/// Captures any array constructor of `length >= i + j`.
|
/// Captures any array constructor of `length >= i + j`.
|
||||||
/// In the case where `array_len` is `Some(_)`,
|
/// In the case where `array_len` is `Some(_)`,
|
||||||
/// this indicates that we only care about the first `i` and the last `j` values of the array,
|
/// this indicates that we only care about the first `i` and the last `j` values of the array,
|
||||||
/// and everything in between is a wildcard `_`.
|
/// and everything in between is a wildcard `_`.
|
||||||
VarLen(u64, u64),
|
VarLen(usize, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SliceKind {
|
impl SliceKind {
|
||||||
fn arity(self) -> u64 {
|
fn arity(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
FixedLen(length) => length,
|
FixedLen(length) => length,
|
||||||
VarLen(prefix, suffix) => prefix + suffix,
|
VarLen(prefix, suffix) => prefix + suffix,
|
||||||
@ -407,7 +407,7 @@ fn arity(self) -> u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this pattern includes patterns of length `other_len`.
|
/// Whether this pattern includes patterns of length `other_len`.
|
||||||
fn covers_length(self, other_len: u64) -> bool {
|
fn covers_length(self, other_len: usize) -> bool {
|
||||||
match self {
|
match self {
|
||||||
FixedLen(len) => len == other_len,
|
FixedLen(len) => len == other_len,
|
||||||
VarLen(prefix, suffix) => prefix + suffix <= other_len,
|
VarLen(prefix, suffix) => prefix + suffix <= other_len,
|
||||||
@ -419,13 +419,13 @@ fn covers_length(self, other_len: u64) -> bool {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub(super) struct Slice {
|
pub(super) struct Slice {
|
||||||
/// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
|
/// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
|
||||||
array_len: Option<u64>,
|
array_len: Option<usize>,
|
||||||
/// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
|
/// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
|
||||||
kind: SliceKind,
|
kind: SliceKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Slice {
|
impl Slice {
|
||||||
fn new(array_len: Option<u64>, kind: SliceKind) -> Self {
|
fn new(array_len: Option<usize>, kind: SliceKind) -> Self {
|
||||||
let kind = match (array_len, kind) {
|
let kind = match (array_len, kind) {
|
||||||
// If the middle `..` is empty, we effectively have a fixed-length pattern.
|
// If the middle `..` is empty, we effectively have a fixed-length pattern.
|
||||||
(Some(len), VarLen(prefix, suffix)) if prefix + suffix >= len => FixedLen(len),
|
(Some(len), VarLen(prefix, suffix)) if prefix + suffix >= len => FixedLen(len),
|
||||||
@ -434,7 +434,7 @@ fn new(array_len: Option<u64>, kind: SliceKind) -> Self {
|
|||||||
Slice { array_len, kind }
|
Slice { array_len, kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(self) -> u64 {
|
fn arity(self) -> usize {
|
||||||
self.kind.arity()
|
self.kind.arity()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,16 +508,16 @@ fn is_covered_by(self, other: Self) -> bool {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SplitVarLenSlice {
|
struct SplitVarLenSlice {
|
||||||
/// If the type is an array, this is its size.
|
/// If the type is an array, this is its size.
|
||||||
array_len: Option<u64>,
|
array_len: Option<usize>,
|
||||||
/// The arity of the input slice.
|
/// The arity of the input slice.
|
||||||
arity: u64,
|
arity: usize,
|
||||||
/// The smallest slice bigger than any slice seen. `max_slice.arity()` is the length `L`
|
/// The smallest slice bigger than any slice seen. `max_slice.arity()` is the length `L`
|
||||||
/// described above.
|
/// described above.
|
||||||
max_slice: SliceKind,
|
max_slice: SliceKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SplitVarLenSlice {
|
impl SplitVarLenSlice {
|
||||||
fn new(prefix: u64, suffix: u64, array_len: Option<u64>) -> Self {
|
fn new(prefix: usize, suffix: usize, array_len: Option<usize>) -> Self {
|
||||||
SplitVarLenSlice { array_len, arity: prefix + suffix, max_slice: VarLen(prefix, suffix) }
|
SplitVarLenSlice { array_len, arity: prefix + suffix, max_slice: VarLen(prefix, suffix) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,12 +687,12 @@ pub(super) fn from_pat<'p>(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &'p Pat<'tcx>) ->
|
|||||||
}
|
}
|
||||||
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
|
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
|
||||||
let array_len = match pat.ty.kind() {
|
let array_len = match pat.ty.kind() {
|
||||||
ty::Array(_, length) => Some(length.eval_usize(cx.tcx, cx.param_env)),
|
ty::Array(_, length) => Some(length.eval_usize(cx.tcx, cx.param_env) as usize),
|
||||||
ty::Slice(_) => None,
|
ty::Slice(_) => None,
|
||||||
_ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty),
|
_ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty),
|
||||||
};
|
};
|
||||||
let prefix = prefix.len() as u64;
|
let prefix = prefix.len();
|
||||||
let suffix = suffix.len() as u64;
|
let suffix = suffix.len();
|
||||||
let kind = if slice.is_some() {
|
let kind = if slice.is_some() {
|
||||||
VarLen(prefix, suffix)
|
VarLen(prefix, suffix)
|
||||||
} else {
|
} else {
|
||||||
@ -885,7 +885,7 @@ pub(super) fn new<'p>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Self {
|
|||||||
let all_ctors = match pcx.ty.kind() {
|
let all_ctors = match pcx.ty.kind() {
|
||||||
ty::Bool => smallvec![make_range(0, 1)],
|
ty::Bool => smallvec![make_range(0, 1)],
|
||||||
ty::Array(sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
|
ty::Array(sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
|
||||||
let len = len.eval_usize(cx.tcx, cx.param_env);
|
let len = len.eval_usize(cx.tcx, cx.param_env) as usize;
|
||||||
if len != 0 && cx.is_uninhabited(sub_ty) {
|
if len != 0 && cx.is_uninhabited(sub_ty) {
|
||||||
smallvec![]
|
smallvec![]
|
||||||
} else {
|
} else {
|
||||||
@ -1273,7 +1273,7 @@ pub(super) fn apply(self, pcx: PatCtxt<'_, 'p, 'tcx>, ctor: &Constructor<'tcx>)
|
|||||||
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
|
PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
|
||||||
}
|
}
|
||||||
VarLen(prefix, _) => {
|
VarLen(prefix, _) => {
|
||||||
let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
|
let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix).collect();
|
||||||
if slice.array_len.is_some() {
|
if slice.array_len.is_some() {
|
||||||
// Improves diagnostics a bit: if the type is a known-size array, instead
|
// Improves diagnostics a bit: if the type is a known-size array, instead
|
||||||
// of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
|
// of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
|
||||||
|
Loading…
Reference in New Issue
Block a user