mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-20 19:04:21 +00:00
Use a Vec
instead of a slice in DeconstructedPat
This commit is contained in:
parent
11f32b73e0
commit
be77cf86ba
@ -119,7 +119,7 @@ pub trait TypeCx: Sized + fmt::Debug {
|
|||||||
/// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
|
/// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
|
||||||
fn write_variant_name(
|
fn write_variant_name(
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
pat: &crate::pat::DeconstructedPat<'_, Self>,
|
pat: &crate::pat::DeconstructedPat<Self>,
|
||||||
) -> fmt::Result;
|
) -> fmt::Result;
|
||||||
|
|
||||||
/// Raise a bug.
|
/// Raise a bug.
|
||||||
@ -130,9 +130,9 @@ pub trait TypeCx: Sized + fmt::Debug {
|
|||||||
/// The default implementation does nothing.
|
/// The default implementation does nothing.
|
||||||
fn lint_overlapping_range_endpoints(
|
fn lint_overlapping_range_endpoints(
|
||||||
&self,
|
&self,
|
||||||
_pat: &DeconstructedPat<'_, Self>,
|
_pat: &DeconstructedPat<Self>,
|
||||||
_overlaps_on: IntRange,
|
_overlaps_on: IntRange,
|
||||||
_overlaps_with: &[&DeconstructedPat<'_, Self>],
|
_overlaps_with: &[&DeconstructedPat<Self>],
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ pub trait TypeCx: Sized + fmt::Debug {
|
|||||||
/// The arm of a match expression.
|
/// The arm of a match expression.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MatchArm<'p, Cx: TypeCx> {
|
pub struct MatchArm<'p, Cx: TypeCx> {
|
||||||
pub pat: &'p DeconstructedPat<'p, Cx>,
|
pub pat: &'p DeconstructedPat<Cx>,
|
||||||
pub has_guard: bool,
|
pub has_guard: bool,
|
||||||
pub arm_data: Cx::ArmData,
|
pub arm_data: Cx::ArmData,
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use std::fmt;
|
|||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use crate::constructor::{Constructor, Slice, SliceKind};
|
use crate::constructor::{Constructor, Slice, SliceKind};
|
||||||
use crate::{Captures, TypeCx};
|
use crate::TypeCx;
|
||||||
|
|
||||||
use self::Constructor::*;
|
use self::Constructor::*;
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ use self::Constructor::*;
|
|||||||
/// This happens if a private or `non_exhaustive` field is uninhabited, because the code mustn't
|
/// This happens if a private or `non_exhaustive` field is uninhabited, because the code mustn't
|
||||||
/// observe that it is uninhabited. In that case that field is not included in `fields`. Care must
|
/// observe that it is uninhabited. In that case that field is not included in `fields`. Care must
|
||||||
/// be taken when converting to/from `thir::Pat`.
|
/// be taken when converting to/from `thir::Pat`.
|
||||||
pub struct DeconstructedPat<'p, Cx: TypeCx> {
|
pub struct DeconstructedPat<Cx: TypeCx> {
|
||||||
ctor: Constructor<Cx>,
|
ctor: Constructor<Cx>,
|
||||||
fields: &'p [DeconstructedPat<'p, Cx>],
|
fields: Vec<DeconstructedPat<Cx>>,
|
||||||
ty: Cx::Ty,
|
ty: Cx::Ty,
|
||||||
/// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not
|
/// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not
|
||||||
/// correspond to a user-supplied pattern.
|
/// correspond to a user-supplied pattern.
|
||||||
@ -32,14 +32,20 @@ pub struct DeconstructedPat<'p, Cx: TypeCx> {
|
|||||||
useful: Cell<bool>,
|
useful: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
|
impl<Cx: TypeCx> DeconstructedPat<Cx> {
|
||||||
pub fn wildcard(ty: Cx::Ty) -> Self {
|
pub fn wildcard(ty: Cx::Ty) -> Self {
|
||||||
DeconstructedPat { ctor: Wildcard, fields: &[], ty, data: None, useful: Cell::new(false) }
|
DeconstructedPat {
|
||||||
|
ctor: Wildcard,
|
||||||
|
fields: Vec::new(),
|
||||||
|
ty,
|
||||||
|
data: None,
|
||||||
|
useful: Cell::new(false),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ctor: Constructor<Cx>,
|
ctor: Constructor<Cx>,
|
||||||
fields: &'p [DeconstructedPat<'p, Cx>],
|
fields: Vec<DeconstructedPat<Cx>>,
|
||||||
ty: Cx::Ty,
|
ty: Cx::Ty,
|
||||||
data: Cx::PatData,
|
data: Cx::PatData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -62,17 +68,17 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
|
|||||||
self.data.as_ref()
|
self.data.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_fields(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'_> {
|
pub fn iter_fields<'a>(&'a self) -> impl Iterator<Item = &'a DeconstructedPat<Cx>> {
|
||||||
self.fields.iter()
|
self.fields.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specialize this pattern with a constructor.
|
/// Specialize this pattern with a constructor.
|
||||||
/// `other_ctor` can be different from `self.ctor`, but must be covered by it.
|
/// `other_ctor` can be different from `self.ctor`, but must be covered by it.
|
||||||
pub(crate) fn specialize(
|
pub(crate) fn specialize<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
other_ctor: &Constructor<Cx>,
|
other_ctor: &Constructor<Cx>,
|
||||||
ctor_arity: usize,
|
ctor_arity: usize,
|
||||||
) -> SmallVec<[PatOrWild<'p, Cx>; 2]> {
|
) -> SmallVec<[PatOrWild<'a, Cx>; 2]> {
|
||||||
let wildcard_sub_tys = || (0..ctor_arity).map(|_| PatOrWild::Wild).collect();
|
let wildcard_sub_tys = || (0..ctor_arity).map(|_| PatOrWild::Wild).collect();
|
||||||
match (&self.ctor, other_ctor) {
|
match (&self.ctor, other_ctor) {
|
||||||
// Return a wildcard for each field of `other_ctor`.
|
// Return a wildcard for each field of `other_ctor`.
|
||||||
@ -139,7 +145,7 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This is best effort and not good enough for a `Display` impl.
|
/// This is best effort and not good enough for a `Display` impl.
|
||||||
impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
|
impl<Cx: TypeCx> fmt::Debug for DeconstructedPat<Cx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let pat = self;
|
let pat = self;
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
@ -221,7 +227,7 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
|
|||||||
/// A non-user-provided wildcard, created during specialization.
|
/// A non-user-provided wildcard, created during specialization.
|
||||||
Wild,
|
Wild,
|
||||||
/// A user-provided pattern.
|
/// A user-provided pattern.
|
||||||
Pat(&'p DeconstructedPat<'p, Cx>),
|
Pat(&'p DeconstructedPat<Cx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
|
impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
|
||||||
@ -236,7 +242,7 @@ impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
|
|||||||
impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}
|
impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
|
impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
|
||||||
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
|
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<Cx>> {
|
||||||
match self {
|
match self {
|
||||||
PatOrWild::Wild => None,
|
PatOrWild::Wild => None,
|
||||||
PatOrWild::Pat(pat) => Some(pat),
|
PatOrWild::Pat(pat) => Some(pat),
|
||||||
|
@ -13,7 +13,7 @@ use crate::{Captures, MatchArm, TypeCx};
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PatternColumn<'p, Cx: TypeCx> {
|
pub struct PatternColumn<'p, Cx: TypeCx> {
|
||||||
/// This must not contain an or-pattern. `expand_and_push` takes care to expand them.
|
/// This must not contain an or-pattern. `expand_and_push` takes care to expand them.
|
||||||
patterns: Vec<&'p DeconstructedPat<'p, Cx>>,
|
patterns: Vec<&'p DeconstructedPat<Cx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
|
impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
|
||||||
@ -41,7 +41,7 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
|
|||||||
pub fn head_ty(&self) -> Option<&Cx::Ty> {
|
pub fn head_ty(&self) -> Option<&Cx::Ty> {
|
||||||
self.patterns.first().map(|pat| pat.ty())
|
self.patterns.first().map(|pat| pat.ty())
|
||||||
}
|
}
|
||||||
pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'a> {
|
pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<Cx>> + Captures<'a> {
|
||||||
self.patterns.iter().copied()
|
self.patterns.iter().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use smallvec::SmallVec;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
|
||||||
@ -27,8 +26,7 @@ use crate::constructor::Constructor::*;
|
|||||||
pub type Constructor<'p, 'tcx> = crate::constructor::Constructor<RustcMatchCheckCtxt<'p, 'tcx>>;
|
pub type Constructor<'p, 'tcx> = crate::constructor::Constructor<RustcMatchCheckCtxt<'p, 'tcx>>;
|
||||||
pub type ConstructorSet<'p, 'tcx> =
|
pub type ConstructorSet<'p, 'tcx> =
|
||||||
crate::constructor::ConstructorSet<RustcMatchCheckCtxt<'p, 'tcx>>;
|
crate::constructor::ConstructorSet<RustcMatchCheckCtxt<'p, 'tcx>>;
|
||||||
pub type DeconstructedPat<'p, 'tcx> =
|
pub type DeconstructedPat<'p, 'tcx> = crate::pat::DeconstructedPat<RustcMatchCheckCtxt<'p, 'tcx>>;
|
||||||
crate::pat::DeconstructedPat<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
|
|
||||||
pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
|
pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
|
||||||
pub type Usefulness<'p, 'tcx> = crate::usefulness::Usefulness<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
|
pub type Usefulness<'p, 'tcx> = crate::usefulness::Usefulness<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
|
||||||
pub type UsefulnessReport<'p, 'tcx> =
|
pub type UsefulnessReport<'p, 'tcx> =
|
||||||
@ -458,21 +456,20 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
/// Note: the input patterns must have been lowered through
|
/// Note: the input patterns must have been lowered through
|
||||||
/// `rustc_mir_build::thir::pattern::check_match::MatchVisitor::lower_pattern`.
|
/// `rustc_mir_build::thir::pattern::check_match::MatchVisitor::lower_pattern`.
|
||||||
pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
|
pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
|
||||||
let singleton = |pat| std::slice::from_ref(self.pattern_arena.alloc(pat));
|
|
||||||
let cx = self;
|
let cx = self;
|
||||||
let ty = cx.reveal_opaque_ty(pat.ty);
|
let ty = cx.reveal_opaque_ty(pat.ty);
|
||||||
let ctor;
|
let ctor;
|
||||||
let fields: &[_];
|
let mut fields: Vec<_>;
|
||||||
match &pat.kind {
|
match &pat.kind {
|
||||||
PatKind::AscribeUserType { subpattern, .. }
|
PatKind::AscribeUserType { subpattern, .. }
|
||||||
| PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
|
| PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
|
||||||
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
|
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
|
||||||
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
||||||
ctor = Wildcard;
|
ctor = Wildcard;
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
PatKind::Deref { subpattern } => {
|
PatKind::Deref { subpattern } => {
|
||||||
fields = singleton(self.lower_pat(subpattern));
|
fields = vec![self.lower_pat(subpattern)];
|
||||||
ctor = match ty.kind() {
|
ctor = match ty.kind() {
|
||||||
// This is a box pattern.
|
// This is a box pattern.
|
||||||
ty::Adt(adt, ..) if adt.is_box() => Struct,
|
ty::Adt(adt, ..) if adt.is_box() => Struct,
|
||||||
@ -484,15 +481,14 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Tuple(fs) => {
|
ty::Tuple(fs) => {
|
||||||
ctor = Struct;
|
ctor = Struct;
|
||||||
let mut wilds: SmallVec<[_; 2]> = fs
|
fields = fs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| cx.reveal_opaque_ty(ty))
|
.map(|ty| cx.reveal_opaque_ty(ty))
|
||||||
.map(|ty| DeconstructedPat::wildcard(ty))
|
.map(|ty| DeconstructedPat::wildcard(ty))
|
||||||
.collect();
|
.collect();
|
||||||
for pat in subpatterns {
|
for pat in subpatterns {
|
||||||
wilds[pat.field.index()] = self.lower_pat(&pat.pattern);
|
fields[pat.field.index()] = self.lower_pat(&pat.pattern);
|
||||||
}
|
}
|
||||||
fields = cx.pattern_arena.alloc_from_iter(wilds);
|
|
||||||
}
|
}
|
||||||
ty::Adt(adt, args) if adt.is_box() => {
|
ty::Adt(adt, args) if adt.is_box() => {
|
||||||
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
||||||
@ -514,7 +510,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
DeconstructedPat::wildcard(self.reveal_opaque_ty(args.type_at(0)))
|
DeconstructedPat::wildcard(self.reveal_opaque_ty(args.type_at(0)))
|
||||||
};
|
};
|
||||||
ctor = Struct;
|
ctor = Struct;
|
||||||
fields = singleton(pat);
|
fields = vec![pat];
|
||||||
}
|
}
|
||||||
ty::Adt(adt, _) => {
|
ty::Adt(adt, _) => {
|
||||||
ctor = match pat.kind {
|
ctor = match pat.kind {
|
||||||
@ -534,14 +530,12 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
ty
|
ty
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let mut wilds: SmallVec<[_; 2]> =
|
fields = tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
|
||||||
tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
|
|
||||||
for pat in subpatterns {
|
for pat in subpatterns {
|
||||||
if let Some(i) = field_id_to_id[pat.field.index()] {
|
if let Some(i) = field_id_to_id[pat.field.index()] {
|
||||||
wilds[i] = self.lower_pat(&pat.pattern);
|
fields[i] = self.lower_pat(&pat.pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fields = cx.pattern_arena.alloc_from_iter(wilds);
|
|
||||||
}
|
}
|
||||||
_ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty),
|
_ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty),
|
||||||
}
|
}
|
||||||
@ -553,7 +547,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
Some(b) => Bool(b),
|
Some(b) => Bool(b),
|
||||||
None => Opaque(OpaqueId::new()),
|
None => Opaque(OpaqueId::new()),
|
||||||
};
|
};
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
ty::Char | ty::Int(_) | ty::Uint(_) => {
|
ty::Char | ty::Int(_) | ty::Uint(_) => {
|
||||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||||
@ -569,7 +563,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
}
|
}
|
||||||
None => Opaque(OpaqueId::new()),
|
None => Opaque(OpaqueId::new()),
|
||||||
};
|
};
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
ty::Float(ty::FloatTy::F32) => {
|
ty::Float(ty::FloatTy::F32) => {
|
||||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||||
@ -580,7 +574,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
}
|
}
|
||||||
None => Opaque(OpaqueId::new()),
|
None => Opaque(OpaqueId::new()),
|
||||||
};
|
};
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
ty::Float(ty::FloatTy::F64) => {
|
ty::Float(ty::FloatTy::F64) => {
|
||||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||||
@ -591,7 +585,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
}
|
}
|
||||||
None => Opaque(OpaqueId::new()),
|
None => Opaque(OpaqueId::new()),
|
||||||
};
|
};
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
ty::Ref(_, t, _) if t.is_str() => {
|
ty::Ref(_, t, _) if t.is_str() => {
|
||||||
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
||||||
@ -602,16 +596,16 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
// subfields.
|
// subfields.
|
||||||
// Note: `t` is `str`, not `&str`.
|
// Note: `t` is `str`, not `&str`.
|
||||||
let ty = self.reveal_opaque_ty(*t);
|
let ty = self.reveal_opaque_ty(*t);
|
||||||
let subpattern = DeconstructedPat::new(Str(*value), &[], ty, pat);
|
let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), ty, pat);
|
||||||
ctor = Ref;
|
ctor = Ref;
|
||||||
fields = singleton(subpattern)
|
fields = vec![subpattern]
|
||||||
}
|
}
|
||||||
// All constants that can be structurally matched have already been expanded
|
// All constants that can be structurally matched have already been expanded
|
||||||
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
|
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
|
||||||
// opaque.
|
// opaque.
|
||||||
_ => {
|
_ => {
|
||||||
ctor = Opaque(OpaqueId::new());
|
ctor = Opaque(OpaqueId::new());
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -648,7 +642,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
}
|
}
|
||||||
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
||||||
};
|
};
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
|
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
|
||||||
let array_len = match ty.kind() {
|
let array_len = match ty.kind() {
|
||||||
@ -664,25 +658,22 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
SliceKind::FixedLen(prefix.len() + suffix.len())
|
SliceKind::FixedLen(prefix.len() + suffix.len())
|
||||||
};
|
};
|
||||||
ctor = Slice(Slice::new(array_len, kind));
|
ctor = Slice(Slice::new(array_len, kind));
|
||||||
fields = cx.pattern_arena.alloc_from_iter(
|
fields = prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)).collect();
|
||||||
prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PatKind::Or { .. } => {
|
PatKind::Or { .. } => {
|
||||||
ctor = Or;
|
ctor = Or;
|
||||||
let pats = expand_or_pat(pat);
|
let pats = expand_or_pat(pat);
|
||||||
fields =
|
fields = pats.into_iter().map(|p| self.lower_pat(p)).collect();
|
||||||
cx.pattern_arena.alloc_from_iter(pats.into_iter().map(|p| self.lower_pat(p)))
|
|
||||||
}
|
}
|
||||||
PatKind::Never => {
|
PatKind::Never => {
|
||||||
// FIXME(never_patterns): handle `!` in exhaustiveness. This is a sane default
|
// FIXME(never_patterns): handle `!` in exhaustiveness. This is a sane default
|
||||||
// in the meantime.
|
// in the meantime.
|
||||||
ctor = Wildcard;
|
ctor = Wildcard;
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
PatKind::Error(_) => {
|
PatKind::Error(_) => {
|
||||||
ctor = Opaque(OpaqueId::new());
|
ctor = Opaque(OpaqueId::new());
|
||||||
fields = &[];
|
fields = vec![];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeconstructedPat::new(ctor, fields, ty, pat)
|
DeconstructedPat::new(ctor, fields, ty, pat)
|
||||||
@ -887,7 +878,7 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
|
|
||||||
fn write_variant_name(
|
fn write_variant_name(
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
pat: &crate::pat::DeconstructedPat<'_, Self>,
|
pat: &crate::pat::DeconstructedPat<Self>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
if let ty::Adt(adt, _) = pat.ty().kind() {
|
if let ty::Adt(adt, _) = pat.ty().kind() {
|
||||||
if adt.is_box() {
|
if adt.is_box() {
|
||||||
@ -906,9 +897,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
|
|||||||
|
|
||||||
fn lint_overlapping_range_endpoints(
|
fn lint_overlapping_range_endpoints(
|
||||||
&self,
|
&self,
|
||||||
pat: &crate::pat::DeconstructedPat<'_, Self>,
|
pat: &crate::pat::DeconstructedPat<Self>,
|
||||||
overlaps_on: IntRange,
|
overlaps_on: IntRange,
|
||||||
overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
|
overlaps_with: &[&crate::pat::DeconstructedPat<Self>],
|
||||||
) {
|
) {
|
||||||
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
|
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
|
||||||
let overlaps: Vec<_> = overlaps_with
|
let overlaps: Vec<_> = overlaps_with
|
||||||
|
@ -848,7 +848,7 @@ impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
|
impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
|
||||||
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
|
fn from_pattern(pat: &'p DeconstructedPat<Cx>) -> Self {
|
||||||
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
|
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,7 +1585,7 @@ pub enum Usefulness<'p, Cx: TypeCx> {
|
|||||||
/// The arm is useful. This additionally carries a set of or-pattern branches that have been
|
/// The arm is useful. This additionally carries a set of or-pattern branches that have been
|
||||||
/// found to be redundant despite the overall arm being useful. Used only in the presence of
|
/// found to be redundant despite the overall arm being useful. Used only in the presence of
|
||||||
/// or-patterns, otherwise it stays empty.
|
/// or-patterns, otherwise it stays empty.
|
||||||
Useful(Vec<&'p DeconstructedPat<'p, Cx>>),
|
Useful(Vec<&'p DeconstructedPat<Cx>>),
|
||||||
/// The arm is redundant and can be removed without changing the behavior of the match
|
/// The arm is redundant and can be removed without changing the behavior of the match
|
||||||
/// expression.
|
/// expression.
|
||||||
Redundant,
|
Redundant,
|
||||||
|
Loading…
Reference in New Issue
Block a user