Store pattern arity in DeconstructedPat
Right now this is just `self.fields.len()` but that'll change in the next commit. `arity` will be useful for the `Debug` impl.
This commit is contained in:
parent
cd81f5b27e
commit
c1e68860d0
@ -423,7 +423,7 @@ pub enum SliceKind {
|
||||
}
|
||||
|
||||
impl SliceKind {
|
||||
fn arity(self) -> usize {
|
||||
pub fn arity(self) -> usize {
|
||||
match self {
|
||||
FixedLen(length) => length,
|
||||
VarLen(prefix, suffix) => prefix + suffix,
|
||||
@ -462,7 +462,7 @@ impl Slice {
|
||||
Slice { array_len, kind }
|
||||
}
|
||||
|
||||
pub(crate) fn arity(self) -> usize {
|
||||
pub fn arity(self) -> usize {
|
||||
self.kind.arity()
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,10 @@ impl PatId {
|
||||
pub struct DeconstructedPat<Cx: TypeCx> {
|
||||
ctor: Constructor<Cx>,
|
||||
fields: Vec<DeconstructedPat<Cx>>,
|
||||
/// The number of fields in this pattern. E.g. if the pattern is `SomeStruct { field12: true, ..
|
||||
/// }` this would be the total number of fields of the struct.
|
||||
/// This is also the same as `self.ctor.arity(self.ty)`.
|
||||
arity: usize,
|
||||
ty: Cx::Ty,
|
||||
/// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not
|
||||
/// correspond to a user-supplied pattern.
|
||||
@ -36,16 +40,24 @@ pub struct DeconstructedPat<Cx: TypeCx> {
|
||||
|
||||
impl<Cx: TypeCx> DeconstructedPat<Cx> {
|
||||
pub fn wildcard(ty: Cx::Ty) -> Self {
|
||||
DeconstructedPat { ctor: Wildcard, fields: Vec::new(), ty, data: None, uid: PatId::new() }
|
||||
DeconstructedPat {
|
||||
ctor: Wildcard,
|
||||
fields: Vec::new(),
|
||||
arity: 0,
|
||||
ty,
|
||||
data: None,
|
||||
uid: PatId::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
ctor: Constructor<Cx>,
|
||||
fields: Vec<DeconstructedPat<Cx>>,
|
||||
arity: usize,
|
||||
ty: Cx::Ty,
|
||||
data: Cx::PatData,
|
||||
) -> Self {
|
||||
DeconstructedPat { ctor, fields, ty, data: Some(data), uid: PatId::new() }
|
||||
DeconstructedPat { ctor, fields, arity, ty, data: Some(data), uid: PatId::new() }
|
||||
}
|
||||
|
||||
pub(crate) fn is_or_pat(&self) -> bool {
|
||||
|
@ -445,6 +445,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
let cx = self;
|
||||
let ty = cx.reveal_opaque_ty(pat.ty);
|
||||
let ctor;
|
||||
let arity;
|
||||
let mut fields: Vec<_>;
|
||||
match &pat.kind {
|
||||
PatKind::AscribeUserType { subpattern, .. }
|
||||
@ -453,9 +454,11 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
||||
ctor = Wildcard;
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
PatKind::Deref { subpattern } => {
|
||||
fields = vec![self.lower_pat(subpattern)];
|
||||
arity = 1;
|
||||
ctor = match ty.kind() {
|
||||
// This is a box pattern.
|
||||
ty::Adt(adt, ..) if adt.is_box() => Struct,
|
||||
@ -467,6 +470,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
match ty.kind() {
|
||||
ty::Tuple(fs) => {
|
||||
ctor = Struct;
|
||||
arity = fs.len();
|
||||
fields = fs
|
||||
.iter()
|
||||
.map(|ty| cx.reveal_opaque_ty(ty))
|
||||
@ -497,6 +501,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
};
|
||||
ctor = Struct;
|
||||
fields = vec![pat];
|
||||
arity = 1;
|
||||
}
|
||||
ty::Adt(adt, _) => {
|
||||
ctor = match pat.kind {
|
||||
@ -507,6 +512,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
};
|
||||
let variant =
|
||||
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
|
||||
arity = variant.fields.len();
|
||||
fields = cx
|
||||
.variant_sub_tys(ty, variant)
|
||||
.map(|(_, ty)| DeconstructedPat::wildcard(ty))
|
||||
@ -526,6 +532,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Char | ty::Int(_) | ty::Uint(_) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
@ -542,6 +549,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F32) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
@ -553,6 +561,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Float(ty::FloatTy::F64) => {
|
||||
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
|
||||
@ -564,6 +573,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
None => Opaque(OpaqueId::new()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
ty::Ref(_, t, _) if t.is_str() => {
|
||||
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
|
||||
@ -574,9 +584,10 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
// subfields.
|
||||
// Note: `t` is `str`, not `&str`.
|
||||
let ty = self.reveal_opaque_ty(*t);
|
||||
let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), ty, pat);
|
||||
let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), 0, ty, pat);
|
||||
ctor = Ref;
|
||||
fields = vec![subpattern]
|
||||
fields = vec![subpattern];
|
||||
arity = 1;
|
||||
}
|
||||
// All constants that can be structurally matched have already been expanded
|
||||
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
|
||||
@ -584,6 +595,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
_ => {
|
||||
ctor = Opaque(OpaqueId::new());
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -623,6 +635,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
_ => bug!("invalid type for range pattern: {}", ty.inner()),
|
||||
};
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
|
||||
let array_len = match ty.kind() {
|
||||
@ -639,11 +652,13 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
};
|
||||
ctor = Slice(Slice::new(array_len, kind));
|
||||
fields = prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)).collect();
|
||||
arity = kind.arity();
|
||||
}
|
||||
PatKind::Or { .. } => {
|
||||
ctor = Or;
|
||||
let pats = expand_or_pat(pat);
|
||||
fields = pats.into_iter().map(|p| self.lower_pat(p)).collect();
|
||||
arity = fields.len();
|
||||
}
|
||||
PatKind::Never => {
|
||||
// A never pattern matches all the values of its type (namely none). Moreover it
|
||||
@ -651,13 +666,15 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
// `Result<!, !>` which has other constructors. Hence we lower it as a wildcard.
|
||||
ctor = Wildcard;
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
PatKind::Error(_) => {
|
||||
ctor = Opaque(OpaqueId::new());
|
||||
fields = vec![];
|
||||
arity = 0;
|
||||
}
|
||||
}
|
||||
DeconstructedPat::new(ctor, fields, ty, pat)
|
||||
DeconstructedPat::new(ctor, fields, arity, ty, pat)
|
||||
}
|
||||
|
||||
/// Convert back to a `thir::PatRangeBoundary` for diagnostic purposes.
|
||||
|
Loading…
x
Reference in New Issue
Block a user