mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-30 08:34:07 +00:00
Auto merge of #101139 - nnethercote:shrink-thir-Pat, r=cjgillot
Shrink `thir::Pat` r? `@cjgillot`
This commit is contained in:
commit
0421444f8f
@ -180,7 +180,7 @@ pub enum StmtKind<'tcx> {
|
||||
/// `let <PAT> = ...`
|
||||
///
|
||||
/// If a type annotation is included, it is added as an ascription pattern.
|
||||
pattern: Pat<'tcx>,
|
||||
pattern: Box<Pat<'tcx>>,
|
||||
|
||||
/// `let pat: ty = <INIT>`
|
||||
initializer: Option<ExprId>,
|
||||
@ -301,7 +301,7 @@ pub enum ExprKind<'tcx> {
|
||||
},
|
||||
Let {
|
||||
expr: ExprId,
|
||||
pat: Pat<'tcx>,
|
||||
pat: Box<Pat<'tcx>>,
|
||||
},
|
||||
/// A `match` expression.
|
||||
Match {
|
||||
@ -467,7 +467,7 @@ pub struct FruInfo<'tcx> {
|
||||
/// A `match` arm.
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct Arm<'tcx> {
|
||||
pub pattern: Pat<'tcx>,
|
||||
pub pattern: Box<Pat<'tcx>>,
|
||||
pub guard: Option<Guard<'tcx>>,
|
||||
pub body: ExprId,
|
||||
pub lint_level: LintLevel,
|
||||
@ -479,7 +479,7 @@ pub struct Arm<'tcx> {
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub enum Guard<'tcx> {
|
||||
If(ExprId),
|
||||
IfLet(Pat<'tcx>, ExprId),
|
||||
IfLet(Box<Pat<'tcx>>, ExprId),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
@ -534,19 +534,19 @@ pub enum BindingMode {
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct FieldPat<'tcx> {
|
||||
pub field: Field,
|
||||
pub pattern: Pat<'tcx>,
|
||||
pub pattern: Box<Pat<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct Pat<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
pub span: Span,
|
||||
pub kind: Box<PatKind<'tcx>>,
|
||||
pub kind: PatKind<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Pat<'tcx> {
|
||||
pub fn wildcard_from_ty(ty: Ty<'tcx>) -> Self {
|
||||
Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) }
|
||||
Pat { ty, span: DUMMY_SP, kind: PatKind::Wild }
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,7 +581,7 @@ pub enum PatKind<'tcx> {
|
||||
|
||||
AscribeUserType {
|
||||
ascription: Ascription<'tcx>,
|
||||
subpattern: Pat<'tcx>,
|
||||
subpattern: Box<Pat<'tcx>>,
|
||||
},
|
||||
|
||||
/// `x`, `ref x`, `x @ P`, etc.
|
||||
@ -591,7 +591,7 @@ pub enum PatKind<'tcx> {
|
||||
mode: BindingMode,
|
||||
var: LocalVarId,
|
||||
ty: Ty<'tcx>,
|
||||
subpattern: Option<Pat<'tcx>>,
|
||||
subpattern: Option<Box<Pat<'tcx>>>,
|
||||
/// Is this the leftmost occurrence of the binding, i.e., is `var` the
|
||||
/// `HirId` of this pattern?
|
||||
is_primary: bool,
|
||||
@ -614,7 +614,7 @@ pub enum PatKind<'tcx> {
|
||||
|
||||
/// `box P`, `&P`, `&mut P`, etc.
|
||||
Deref {
|
||||
subpattern: Pat<'tcx>,
|
||||
subpattern: Box<Pat<'tcx>>,
|
||||
},
|
||||
|
||||
/// One of the following:
|
||||
@ -628,32 +628,32 @@ pub enum PatKind<'tcx> {
|
||||
value: mir::ConstantKind<'tcx>,
|
||||
},
|
||||
|
||||
Range(PatRange<'tcx>),
|
||||
Range(Box<PatRange<'tcx>>),
|
||||
|
||||
/// Matches against a slice, checking the length and extracting elements.
|
||||
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
|
||||
/// e.g., `&[ref xs @ ..]`.
|
||||
Slice {
|
||||
prefix: Vec<Pat<'tcx>>,
|
||||
slice: Option<Pat<'tcx>>,
|
||||
suffix: Vec<Pat<'tcx>>,
|
||||
prefix: Box<[Box<Pat<'tcx>>]>,
|
||||
slice: Option<Box<Pat<'tcx>>>,
|
||||
suffix: Box<[Box<Pat<'tcx>>]>,
|
||||
},
|
||||
|
||||
/// Fixed match against an array; irrefutable.
|
||||
Array {
|
||||
prefix: Vec<Pat<'tcx>>,
|
||||
slice: Option<Pat<'tcx>>,
|
||||
suffix: Vec<Pat<'tcx>>,
|
||||
prefix: Box<[Box<Pat<'tcx>>]>,
|
||||
slice: Option<Box<Pat<'tcx>>>,
|
||||
suffix: Box<[Box<Pat<'tcx>>]>,
|
||||
},
|
||||
|
||||
/// An or-pattern, e.g. `p | q`.
|
||||
/// Invariant: `pats.len() >= 2`.
|
||||
Or {
|
||||
pats: Vec<Pat<'tcx>>,
|
||||
pats: Box<[Box<Pat<'tcx>>]>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
|
||||
#[derive(Clone, Debug, PartialEq, HashStable)]
|
||||
pub struct PatRange<'tcx> {
|
||||
pub lo: mir::ConstantKind<'tcx>,
|
||||
pub hi: mir::ConstantKind<'tcx>,
|
||||
@ -674,7 +674,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
||||
};
|
||||
let mut start_or_comma = || start_or_continue(", ");
|
||||
|
||||
match *self.kind {
|
||||
match self.kind {
|
||||
PatKind::Wild => write!(f, "_"),
|
||||
PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern),
|
||||
PatKind::Binding { mutability, name, mode, ref subpattern, .. } => {
|
||||
@ -695,7 +695,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
|
||||
let variant = match *self.kind {
|
||||
let variant = match self.kind {
|
||||
PatKind::Variant { adt_def, variant_index, .. } => {
|
||||
Some(adt_def.variant(variant_index))
|
||||
}
|
||||
@ -714,7 +714,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
||||
|
||||
let mut printed = 0;
|
||||
for p in subpatterns {
|
||||
if let PatKind::Wild = *p.pattern.kind {
|
||||
if let PatKind::Wild = p.pattern.kind {
|
||||
continue;
|
||||
}
|
||||
let name = variant.fields[p.field.index()].name;
|
||||
@ -767,7 +767,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
||||
write!(f, "{}", subpattern)
|
||||
}
|
||||
PatKind::Constant { value } => write!(f, "{}", value),
|
||||
PatKind::Range(PatRange { lo, hi, end }) => {
|
||||
PatKind::Range(box PatRange { lo, hi, end }) => {
|
||||
write!(f, "{}", lo)?;
|
||||
write!(f, "{}", end)?;
|
||||
write!(f, "{}", hi)
|
||||
@ -775,24 +775,24 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
|
||||
PatKind::Slice { ref prefix, ref slice, ref suffix }
|
||||
| PatKind::Array { ref prefix, ref slice, ref suffix } => {
|
||||
write!(f, "[")?;
|
||||
for p in prefix {
|
||||
for p in prefix.iter() {
|
||||
write!(f, "{}{}", start_or_comma(), p)?;
|
||||
}
|
||||
if let Some(ref slice) = *slice {
|
||||
write!(f, "{}", start_or_comma())?;
|
||||
match *slice.kind {
|
||||
match slice.kind {
|
||||
PatKind::Wild => {}
|
||||
_ => write!(f, "{}", slice)?,
|
||||
}
|
||||
write!(f, "..")?;
|
||||
}
|
||||
for p in suffix {
|
||||
for p in suffix.iter() {
|
||||
write!(f, "{}{}", start_or_comma(), p)?;
|
||||
}
|
||||
write!(f, "]")
|
||||
}
|
||||
PatKind::Or { ref pats } => {
|
||||
for pat in pats {
|
||||
for pat in pats.iter() {
|
||||
write!(f, "{}{}", start_or_continue(" | "), pat)?;
|
||||
}
|
||||
Ok(())
|
||||
@ -809,8 +809,8 @@ mod size_asserts {
|
||||
static_assert_size!(Block, 56);
|
||||
static_assert_size!(Expr<'_>, 64);
|
||||
static_assert_size!(ExprKind<'_>, 40);
|
||||
static_assert_size!(Pat<'_>, 24);
|
||||
static_assert_size!(PatKind<'_>, 112);
|
||||
static_assert_size!(Stmt<'_>, 72);
|
||||
static_assert_size!(StmtKind<'_>, 64);
|
||||
static_assert_size!(Pat<'_>, 72);
|
||||
static_assert_size!(PatKind<'_>, 56);
|
||||
static_assert_size!(Stmt<'_>, 56);
|
||||
static_assert_size!(StmtKind<'_>, 48);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'
|
||||
|
||||
pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
|
||||
use PatKind::*;
|
||||
match pat.kind.as_ref() {
|
||||
match &pat.kind {
|
||||
AscribeUserType { subpattern, ascription: _ }
|
||||
| Deref { subpattern }
|
||||
| Binding {
|
||||
@ -232,18 +232,18 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
|
||||
Constant { value: _ } => {}
|
||||
Range(_) => {}
|
||||
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
|
||||
for subpattern in prefix {
|
||||
for subpattern in prefix.iter() {
|
||||
visitor.visit_pat(&subpattern);
|
||||
}
|
||||
if let Some(pat) = slice {
|
||||
visitor.visit_pat(pat);
|
||||
visitor.visit_pat(&pat);
|
||||
}
|
||||
for subpattern in suffix {
|
||||
for subpattern in suffix.iter() {
|
||||
visitor.visit_pat(&subpattern);
|
||||
}
|
||||
}
|
||||
Or { pats } => {
|
||||
for pat in pats {
|
||||
for pat in pats.iter() {
|
||||
visitor.visit_pat(&pat);
|
||||
}
|
||||
}
|
||||
|
@ -874,7 +874,7 @@ pub type CanonicalUserTypeAnnotations<'tcx> =
|
||||
|
||||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct CanonicalUserTypeAnnotation<'tcx> {
|
||||
pub user_ty: CanonicalUserType<'tcx>,
|
||||
pub user_ty: Box<CanonicalUserType<'tcx>>,
|
||||
pub span: Span,
|
||||
pub inferred_ty: Ty<'tcx>,
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
lint_level,
|
||||
else_block,
|
||||
} => {
|
||||
let ignores_expr_result = matches!(*pattern.kind, PatKind::Wild);
|
||||
let ignores_expr_result = matches!(pattern.kind, PatKind::Wild);
|
||||
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
|
||||
|
||||
// Enter the remainder scope, i.e., the bindings' destruction scope.
|
||||
@ -160,7 +160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
ArmHasGuard(false),
|
||||
Some((None, initializer_span)),
|
||||
);
|
||||
this.expr_into_pattern(block, pattern.clone(), init) // irrefutable pattern
|
||||
this.expr_into_pattern(block, pattern, init) // irrefutable pattern
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -42,10 +42,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Constant { span, user_ty: None, literal }
|
||||
}
|
||||
ExprKind::NonHirLiteral { lit, ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
let user_ty = user_ty.as_ref().map(|user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
@ -54,10 +54,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Constant { span, user_ty: user_ty, literal }
|
||||
}
|
||||
ExprKind::ZstLiteral { ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
let user_ty = user_ty.as_ref().map(|user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
@ -66,10 +66,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Constant { span, user_ty: user_ty, literal }
|
||||
}
|
||||
ExprKind::NamedConst { def_id, substs, ref user_ty } => {
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
let user_ty = user_ty.as_ref().map(|user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: ty,
|
||||
})
|
||||
});
|
||||
|
@ -522,11 +522,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
fake_borrow_temps,
|
||||
)
|
||||
);
|
||||
if let Some(box user_ty) = user_ty {
|
||||
if let Some(user_ty) = user_ty {
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
|
||||
@ -551,11 +551,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let source = &this.thir[source];
|
||||
let temp =
|
||||
unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability));
|
||||
if let Some(box user_ty) = user_ty {
|
||||
if let Some(user_ty) = user_ty {
|
||||
let annotation_index =
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty: expr.ty,
|
||||
});
|
||||
this.cfg.push(
|
||||
|
@ -378,10 +378,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let inferred_ty = expr.ty;
|
||||
let user_ty = user_ty.as_ref().map(|box user_ty| {
|
||||
let user_ty = user_ty.as_ref().map(|user_ty| {
|
||||
this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
|
||||
span: source_info.span,
|
||||
user_ty: *user_ty,
|
||||
user_ty: user_ty.clone(),
|
||||
inferred_ty,
|
||||
})
|
||||
});
|
||||
|
@ -490,10 +490,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
pub(super) fn expr_into_pattern(
|
||||
&mut self,
|
||||
mut block: BasicBlock,
|
||||
irrefutable_pat: Pat<'tcx>,
|
||||
irrefutable_pat: &Pat<'tcx>,
|
||||
initializer: &Expr<'tcx>,
|
||||
) -> BlockAnd<()> {
|
||||
match *irrefutable_pat.kind {
|
||||
match irrefutable_pat.kind {
|
||||
// Optimize the case of `let x = ...` to write directly into `x`
|
||||
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
|
||||
let place =
|
||||
@ -518,17 +518,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// broken.
|
||||
PatKind::AscribeUserType {
|
||||
subpattern:
|
||||
Pat {
|
||||
box Pat {
|
||||
kind:
|
||||
box PatKind::Binding {
|
||||
mode: BindingMode::ByValue,
|
||||
var,
|
||||
subpattern: None,
|
||||
..
|
||||
PatKind::Binding {
|
||||
mode: BindingMode::ByValue, var, subpattern: None, ..
|
||||
},
|
||||
..
|
||||
},
|
||||
ascription: thir::Ascription { annotation, variance: _ },
|
||||
ascription: thir::Ascription { ref annotation, variance: _ },
|
||||
} => {
|
||||
let place =
|
||||
self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
|
||||
@ -541,7 +538,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let ty_source_info = self.source_info(annotation.span);
|
||||
|
||||
let base = self.canonical_user_type_annotations.push(annotation);
|
||||
let base = self.canonical_user_type_annotations.push(annotation.clone());
|
||||
self.cfg.push(
|
||||
block,
|
||||
Statement {
|
||||
@ -581,7 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
pub(crate) fn place_into_pattern(
|
||||
&mut self,
|
||||
block: BasicBlock,
|
||||
irrefutable_pat: Pat<'tcx>,
|
||||
irrefutable_pat: &Pat<'tcx>,
|
||||
initializer: PlaceBuilder<'tcx>,
|
||||
set_match_place: bool,
|
||||
) -> BlockAnd<()> {
|
||||
@ -744,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
"visit_primary_bindings: pattern={:?} pattern_user_ty={:?}",
|
||||
pattern, pattern_user_ty
|
||||
);
|
||||
match *pattern.kind {
|
||||
match pattern.kind {
|
||||
PatKind::Binding {
|
||||
mutability,
|
||||
name,
|
||||
@ -767,7 +764,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
| PatKind::Slice { ref prefix, ref slice, ref suffix } => {
|
||||
let from = u64::try_from(prefix.len()).unwrap();
|
||||
let to = u64::try_from(suffix.len()).unwrap();
|
||||
for subpattern in prefix {
|
||||
for subpattern in prefix.iter() {
|
||||
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
|
||||
}
|
||||
for subpattern in slice {
|
||||
@ -777,7 +774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
f,
|
||||
);
|
||||
}
|
||||
for subpattern in suffix {
|
||||
for subpattern in suffix.iter() {
|
||||
self.visit_primary_bindings(subpattern, pattern_user_ty.clone().index(), f);
|
||||
}
|
||||
}
|
||||
@ -830,7 +827,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// may not all be in the leftmost subpattern. For example in
|
||||
// `let (x | y) = ...`, the primary binding of `y` occurs in
|
||||
// the right subpattern
|
||||
for subpattern in pats {
|
||||
for subpattern in pats.iter() {
|
||||
self.visit_primary_bindings(subpattern, pattern_user_ty.clone(), f);
|
||||
}
|
||||
}
|
||||
@ -982,7 +979,7 @@ enum TestKind<'tcx> {
|
||||
},
|
||||
|
||||
/// Test whether the value falls within an inclusive or exclusive range
|
||||
Range(PatRange<'tcx>),
|
||||
Range(Box<PatRange<'tcx>>),
|
||||
|
||||
/// Test that the length of the slice is equal to `len`.
|
||||
Len { len: u64, op: BinOp },
|
||||
@ -1330,7 +1327,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
// All of the or-patterns have been sorted to the end, so if the first
|
||||
// pattern is an or-pattern we only have or-patterns.
|
||||
match *first_candidate.match_pairs[0].pattern.kind {
|
||||
match first_candidate.match_pairs[0].pattern.kind {
|
||||
PatKind::Or { .. } => (),
|
||||
_ => {
|
||||
self.test_candidates(
|
||||
@ -1350,7 +1347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
let mut otherwise = None;
|
||||
for match_pair in match_pairs {
|
||||
let PatKind::Or { ref pats } = &*match_pair.pattern.kind else {
|
||||
let PatKind::Or { ref pats } = &match_pair.pattern.kind else {
|
||||
bug!("Or-patterns should have been sorted to the end");
|
||||
};
|
||||
let or_span = match_pair.pattern.span;
|
||||
@ -1384,7 +1381,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut self,
|
||||
candidate: &mut Candidate<'pat, 'tcx>,
|
||||
otherwise: &mut Option<BasicBlock>,
|
||||
pats: &'pat [Pat<'tcx>],
|
||||
pats: &'pat [Box<Pat<'tcx>>],
|
||||
or_span: Span,
|
||||
place: PlaceBuilder<'tcx>,
|
||||
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
|
||||
@ -2289,7 +2286,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let else_block_span = self.thir[else_block].span;
|
||||
let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| {
|
||||
let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span));
|
||||
let pat = Pat { ty: init.ty, span: else_block_span, kind: Box::new(PatKind::Wild) };
|
||||
let pat = Pat { ty: init.ty, span: else_block_span, kind: PatKind::Wild };
|
||||
let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
|
||||
this.declare_bindings(
|
||||
visibility_scope,
|
||||
|
@ -67,7 +67,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
loop {
|
||||
let match_pairs = mem::take(&mut candidate.match_pairs);
|
||||
|
||||
if let [MatchPair { pattern: Pat { kind: box PatKind::Or { pats }, .. }, place }] =
|
||||
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
|
||||
&*match_pairs
|
||||
{
|
||||
existing_bindings.extend_from_slice(&new_bindings);
|
||||
@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// late as possible.
|
||||
candidate
|
||||
.match_pairs
|
||||
.sort_by_key(|pair| matches!(*pair.pattern.kind, PatKind::Or { .. }));
|
||||
.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
|
||||
debug!(simplified = ?candidate, "simplify_candidate");
|
||||
return false; // if we were not able to simplify any, done.
|
||||
}
|
||||
@ -127,10 +127,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut self,
|
||||
candidate: &Candidate<'pat, 'tcx>,
|
||||
place: PlaceBuilder<'tcx>,
|
||||
pats: &'pat [Pat<'tcx>],
|
||||
pats: &'pat [Box<Pat<'tcx>>],
|
||||
) -> Vec<Candidate<'pat, 'tcx>> {
|
||||
pats.iter()
|
||||
.map(|pat| {
|
||||
.map(|box pat| {
|
||||
let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard);
|
||||
self.simplify_candidate(&mut candidate);
|
||||
candidate
|
||||
@ -149,7 +149,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
candidate: &mut Candidate<'pat, 'tcx>,
|
||||
) -> Result<(), MatchPair<'pat, 'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
match *match_pair.pattern.kind {
|
||||
match match_pair.pattern.kind {
|
||||
PatKind::AscribeUserType {
|
||||
ref subpattern,
|
||||
ascription: thir::Ascription { ref annotation, variance },
|
||||
@ -208,7 +208,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Err(match_pair)
|
||||
}
|
||||
|
||||
PatKind::Range(PatRange { lo, hi, end }) => {
|
||||
PatKind::Range(box PatRange { lo, hi, end }) => {
|
||||
let (range, bias) = match *lo.ty().kind() {
|
||||
ty::Char => {
|
||||
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
|
||||
@ -254,7 +254,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut candidate.match_pairs,
|
||||
&match_pair.place,
|
||||
prefix,
|
||||
slice.as_ref(),
|
||||
slice,
|
||||
suffix,
|
||||
);
|
||||
Ok(())
|
||||
@ -294,7 +294,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut candidate.match_pairs,
|
||||
&match_pair.place,
|
||||
prefix,
|
||||
slice.as_ref(),
|
||||
slice,
|
||||
suffix,
|
||||
);
|
||||
Ok(())
|
||||
|
@ -29,7 +29,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
///
|
||||
/// It is a bug to call this with a not-fully-simplified pattern.
|
||||
pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
|
||||
match *match_pair.pattern.kind {
|
||||
match match_pair.pattern.kind {
|
||||
PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
|
||||
span: match_pair.pattern.span,
|
||||
kind: TestKind::Switch {
|
||||
@ -58,10 +58,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
kind: TestKind::Eq { value, ty: match_pair.pattern.ty },
|
||||
},
|
||||
|
||||
PatKind::Range(range) => {
|
||||
PatKind::Range(ref range) => {
|
||||
assert_eq!(range.lo.ty(), match_pair.pattern.ty);
|
||||
assert_eq!(range.hi.ty(), match_pair.pattern.ty);
|
||||
Test { span: match_pair.pattern.span, kind: TestKind::Range(range) }
|
||||
Test { span: match_pair.pattern.span, kind: TestKind::Range(range.clone()) }
|
||||
}
|
||||
|
||||
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
|
||||
@ -92,7 +92,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
|
||||
match *match_pair.pattern.kind {
|
||||
match match_pair.pattern.kind {
|
||||
PatKind::Constant { value } => {
|
||||
options
|
||||
.entry(value)
|
||||
@ -102,9 +102,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
PatKind::Variant { .. } => {
|
||||
panic!("you should have called add_variants_to_switch instead!");
|
||||
}
|
||||
PatKind::Range(range) => {
|
||||
PatKind::Range(ref range) => {
|
||||
// Check that none of the switch values are in the range.
|
||||
self.values_not_contained_in_range(range, options).unwrap_or(false)
|
||||
self.values_not_contained_in_range(&*range, options).unwrap_or(false)
|
||||
}
|
||||
PatKind::Slice { .. }
|
||||
| PatKind::Array { .. }
|
||||
@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
|
||||
match *match_pair.pattern.kind {
|
||||
match match_pair.pattern.kind {
|
||||
PatKind::Variant { adt_def: _, variant_index, .. } => {
|
||||
// We have a pattern testing for variant `variant_index`
|
||||
// set the corresponding index to true
|
||||
@ -272,7 +272,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
TestKind::Range(PatRange { lo, hi, ref end }) => {
|
||||
TestKind::Range(box PatRange { lo, hi, ref end }) => {
|
||||
let lower_bound_success = self.cfg.start_new_block();
|
||||
let target_blocks = make_target_blocks(self);
|
||||
|
||||
@ -506,7 +506,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let (match_pair_index, match_pair) =
|
||||
candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == *test_place)?;
|
||||
|
||||
match (&test.kind, &*match_pair.pattern.kind) {
|
||||
match (&test.kind, &match_pair.pattern.kind) {
|
||||
// If we are performing a variant switch, then this
|
||||
// informs variant patterns, but nothing else.
|
||||
(
|
||||
@ -540,9 +540,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Some(index)
|
||||
}
|
||||
|
||||
(&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(range)) => {
|
||||
(&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(ref range)) => {
|
||||
let not_contained =
|
||||
self.values_not_contained_in_range(range, options).unwrap_or(false);
|
||||
self.values_not_contained_in_range(&*range, options).unwrap_or(false);
|
||||
|
||||
if not_contained {
|
||||
// No switch values are contained in the pattern range,
|
||||
@ -569,7 +569,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
match_pair_index,
|
||||
candidate,
|
||||
prefix,
|
||||
slice.as_ref(),
|
||||
slice,
|
||||
suffix,
|
||||
);
|
||||
Some(0)
|
||||
@ -607,7 +607,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
match_pair_index,
|
||||
candidate,
|
||||
prefix,
|
||||
slice.as_ref(),
|
||||
slice,
|
||||
suffix,
|
||||
);
|
||||
Some(0)
|
||||
@ -631,7 +631,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
(&TestKind::Range(test), &PatKind::Range(pat)) => {
|
||||
(&TestKind::Range(ref test), &PatKind::Range(ref pat)) => {
|
||||
use std::cmp::Ordering::*;
|
||||
|
||||
if test == pat {
|
||||
@ -658,8 +658,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
no_overlap
|
||||
}
|
||||
|
||||
(&TestKind::Range(range), &PatKind::Constant { value }) => {
|
||||
if let Some(false) = self.const_range_contains(range, value) {
|
||||
(&TestKind::Range(ref range), &PatKind::Constant { value }) => {
|
||||
if let Some(false) = self.const_range_contains(&*range, value) {
|
||||
// `value` is not contained in the testing range,
|
||||
// so `value` can be matched only if this test fails.
|
||||
Some(1)
|
||||
@ -678,7 +678,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
// However, at this point we can still encounter or-patterns that were extracted
|
||||
// from previous calls to `sort_candidate`, so we need to manually address that
|
||||
// case to avoid panicking in `self.test()`.
|
||||
if let PatKind::Or { .. } = &*match_pair.pattern.kind {
|
||||
if let PatKind::Or { .. } = &match_pair.pattern.kind {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -708,9 +708,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut self,
|
||||
match_pair_index: usize,
|
||||
candidate: &mut Candidate<'pat, 'tcx>,
|
||||
prefix: &'pat [Pat<'tcx>],
|
||||
opt_slice: Option<&'pat Pat<'tcx>>,
|
||||
suffix: &'pat [Pat<'tcx>],
|
||||
prefix: &'pat [Box<Pat<'tcx>>],
|
||||
opt_slice: &'pat Option<Box<Pat<'tcx>>>,
|
||||
suffix: &'pat [Box<Pat<'tcx>>],
|
||||
) {
|
||||
let removed_place = candidate.match_pairs.remove(match_pair_index).place;
|
||||
self.prefix_slice_suffix(
|
||||
@ -754,7 +754,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
fn const_range_contains(
|
||||
&self,
|
||||
range: PatRange<'tcx>,
|
||||
range: &PatRange<'tcx>,
|
||||
value: ConstantKind<'tcx>,
|
||||
) -> Option<bool> {
|
||||
use std::cmp::Ordering::*;
|
||||
@ -772,7 +772,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
|
||||
fn values_not_contained_in_range(
|
||||
&self,
|
||||
range: PatRange<'tcx>,
|
||||
range: &PatRange<'tcx>,
|
||||
options: &FxIndexMap<ConstantKind<'tcx>, u128>,
|
||||
) -> Option<bool> {
|
||||
for &val in options.keys() {
|
||||
|
@ -26,9 +26,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
&mut self,
|
||||
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
|
||||
place: &PlaceBuilder<'tcx>,
|
||||
prefix: &'pat [Pat<'tcx>],
|
||||
opt_slice: Option<&'pat Pat<'tcx>>,
|
||||
suffix: &'pat [Pat<'tcx>],
|
||||
prefix: &'pat [Box<Pat<'tcx>>],
|
||||
opt_slice: &'pat Option<Box<Pat<'tcx>>>,
|
||||
suffix: &'pat [Box<Pat<'tcx>>],
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let (min_length, exact_size) = if let Ok(place_resolved) =
|
||||
|
@ -1015,7 +1015,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
let original_source_scope = self.source_scope;
|
||||
let span = pattern.span;
|
||||
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
|
||||
match *pattern.kind {
|
||||
match pattern.kind {
|
||||
// Don't introduce extra copies for simple bindings
|
||||
PatKind::Binding {
|
||||
mutability,
|
||||
@ -1052,7 +1052,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
Some((Some(&place), span)),
|
||||
);
|
||||
let place_builder = PlaceBuilder::from(local);
|
||||
unpack!(block = self.place_into_pattern(block, pattern, place_builder, false));
|
||||
unpack!(
|
||||
block =
|
||||
self.place_into_pattern(block, pattern.as_ref(), place_builder, false)
|
||||
);
|
||||
}
|
||||
}
|
||||
self.source_scope = original_source_scope;
|
||||
|
@ -214,7 +214,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_pat(&mut self, pat: &Pat<'tcx>) {
|
||||
if self.in_union_destructure {
|
||||
match *pat.kind {
|
||||
match pat.kind {
|
||||
// binding to a variable allows getting stuff out of variable
|
||||
PatKind::Binding { .. }
|
||||
// match is conditional on having this value
|
||||
@ -236,7 +236,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
match &*pat.kind {
|
||||
match &pat.kind {
|
||||
PatKind::Leaf { .. } => {
|
||||
if let ty::Adt(adt_def, ..) = pat.ty.kind() {
|
||||
if adt_def.is_union() {
|
||||
|
@ -87,21 +87,21 @@ impl<'tcx> Cx<'tcx> {
|
||||
{
|
||||
debug!("mirror_stmts: user_ty={:?}", user_ty);
|
||||
let annotation = CanonicalUserTypeAnnotation {
|
||||
user_ty,
|
||||
user_ty: Box::new(user_ty),
|
||||
span: ty.span,
|
||||
inferred_ty: self.typeck_results.node_type(ty.hir_id),
|
||||
};
|
||||
pattern = Pat {
|
||||
pattern = Box::new(Pat {
|
||||
ty: pattern.ty,
|
||||
span: pattern.span,
|
||||
kind: Box::new(PatKind::AscribeUserType {
|
||||
kind: PatKind::AscribeUserType {
|
||||
ascription: Ascription {
|
||||
annotation,
|
||||
variance: ty::Variance::Covariant,
|
||||
},
|
||||
subpattern: pattern,
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Pat<'tcx> {
|
||||
pub(crate) fn pattern_from_hir(&mut self, p: &hir::Pat<'_>) -> Box<Pat<'tcx>> {
|
||||
let p = match self.tcx.hir().get(p.hir_id) {
|
||||
Node::Pat(p) => p,
|
||||
node => bug!("pattern became {:?}", node),
|
||||
|
@ -26,7 +26,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
id: hir::HirId,
|
||||
span: Span,
|
||||
mir_structural_match_violation: bool,
|
||||
) -> Pat<'tcx> {
|
||||
) -> Box<Pat<'tcx>> {
|
||||
self.tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut convert = ConstToPat::new(self, id, span, infcx);
|
||||
convert.to_pat(cv, mir_structural_match_violation)
|
||||
@ -156,7 +156,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
&mut self,
|
||||
cv: mir::ConstantKind<'tcx>,
|
||||
mir_structural_match_violation: bool,
|
||||
) -> Pat<'tcx> {
|
||||
) -> Box<Pat<'tcx>> {
|
||||
trace!(self.treat_byte_string_as_slice);
|
||||
// This method is just a wrapper handling a validity check; the heavy lifting is
|
||||
// performed by the recursive `recur` method, which is not meant to be
|
||||
@ -166,10 +166,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
// level of indirection can be eliminated
|
||||
|
||||
let inlined_const_as_pat =
|
||||
self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| Pat {
|
||||
span: self.span,
|
||||
ty: cv.ty(),
|
||||
kind: Box::new(PatKind::Constant { value: cv }),
|
||||
self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| {
|
||||
Box::new(Pat {
|
||||
span: self.span,
|
||||
ty: cv.ty(),
|
||||
kind: PatKind::Constant { value: cv },
|
||||
})
|
||||
});
|
||||
|
||||
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
||||
@ -271,7 +273,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
&self,
|
||||
cv: mir::ConstantKind<'tcx>,
|
||||
mir_structural_match_violation: bool,
|
||||
) -> Result<Pat<'tcx>, FallbackToConstRef> {
|
||||
) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
|
||||
let id = self.id;
|
||||
let span = self.span;
|
||||
let tcx = self.tcx();
|
||||
@ -398,7 +400,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
.map(|val| self.recur(*val, false))
|
||||
.collect::<Result<_, _>>()?,
|
||||
slice: None,
|
||||
suffix: Vec::new(),
|
||||
suffix: Box::new([]),
|
||||
},
|
||||
ty::Ref(_, pointee_ty, ..) => match *pointee_ty.kind() {
|
||||
// These are not allowed and will error elsewhere anyway.
|
||||
@ -425,8 +427,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
let old = self.behind_reference.replace(true);
|
||||
let array = tcx.deref_mir_constant(self.param_env.and(cv));
|
||||
let val = PatKind::Deref {
|
||||
subpattern: Pat {
|
||||
kind: Box::new(PatKind::Array {
|
||||
subpattern: Box::new(Pat {
|
||||
kind: PatKind::Array {
|
||||
prefix: tcx
|
||||
.destructure_mir_constant(param_env, array)
|
||||
.fields
|
||||
@ -434,11 +436,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
.map(|val| self.recur(*val, false))
|
||||
.collect::<Result<_, _>>()?,
|
||||
slice: None,
|
||||
suffix: vec![],
|
||||
}),
|
||||
suffix: Box::new([]),
|
||||
},
|
||||
span,
|
||||
ty: *pointee_ty,
|
||||
},
|
||||
}),
|
||||
};
|
||||
self.behind_reference.set(old);
|
||||
val
|
||||
@ -451,8 +453,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
let old = self.behind_reference.replace(true);
|
||||
let array = tcx.deref_mir_constant(self.param_env.and(cv));
|
||||
let val = PatKind::Deref {
|
||||
subpattern: Pat {
|
||||
kind: Box::new(PatKind::Slice {
|
||||
subpattern: Box::new(Pat {
|
||||
kind: PatKind::Slice {
|
||||
prefix: tcx
|
||||
.destructure_mir_constant(param_env, array)
|
||||
.fields
|
||||
@ -460,11 +462,11 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
.map(|val| self.recur(*val, false))
|
||||
.collect::<Result<_, _>>()?,
|
||||
slice: None,
|
||||
suffix: vec![],
|
||||
}),
|
||||
suffix: Box::new([]),
|
||||
},
|
||||
span,
|
||||
ty: tcx.mk_slice(elem_ty),
|
||||
},
|
||||
}),
|
||||
};
|
||||
self.behind_reference.set(old);
|
||||
val
|
||||
@ -598,6 +600,6 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
Ok(Pat { span, ty: cv.ty(), kind: Box::new(kind) })
|
||||
Ok(Box::new(Pat { span, ty: cv.ty(), kind }))
|
||||
}
|
||||
}
|
||||
|
@ -71,9 +71,9 @@ use std::ops::RangeInclusive;
|
||||
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
|
||||
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
|
||||
fn expand<'p, 'tcx>(pat: &'p Pat<'tcx>, vec: &mut Vec<&'p Pat<'tcx>>) {
|
||||
if let PatKind::Or { pats } = pat.kind.as_ref() {
|
||||
for pat in pats {
|
||||
expand(pat, vec);
|
||||
if let PatKind::Or { pats } = &pat.kind {
|
||||
for pat in pats.iter() {
|
||||
expand(&pat, vec);
|
||||
}
|
||||
} else {
|
||||
vec.push(pat)
|
||||
@ -252,10 +252,14 @@ impl IntRange {
|
||||
let kind = if lo == hi {
|
||||
PatKind::Constant { value: lo_const }
|
||||
} else {
|
||||
PatKind::Range(PatRange { lo: lo_const, hi: hi_const, end: RangeEnd::Included })
|
||||
PatKind::Range(Box::new(PatRange {
|
||||
lo: lo_const,
|
||||
hi: hi_const,
|
||||
end: RangeEnd::Included,
|
||||
}))
|
||||
};
|
||||
|
||||
Pat { ty, span: DUMMY_SP, kind: Box::new(kind) }
|
||||
Pat { ty, span: DUMMY_SP, kind }
|
||||
}
|
||||
|
||||
/// Lint on likely incorrect range patterns (#63987)
|
||||
@ -1297,7 +1301,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
let mkpat = |pat| DeconstructedPat::from_pat(cx, pat);
|
||||
let ctor;
|
||||
let fields;
|
||||
match pat.kind.as_ref() {
|
||||
match &pat.kind {
|
||||
PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern),
|
||||
PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat),
|
||||
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
|
||||
@ -1342,9 +1346,9 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
fields = Fields::singleton(cx, pat);
|
||||
}
|
||||
ty::Adt(adt, _) => {
|
||||
ctor = match pat.kind.as_ref() {
|
||||
ctor = match pat.kind {
|
||||
PatKind::Leaf { .. } => Single,
|
||||
PatKind::Variant { variant_index, .. } => Variant(*variant_index),
|
||||
PatKind::Variant { variant_index, .. } => Variant(variant_index),
|
||||
_ => bug!(),
|
||||
};
|
||||
let variant = &adt.variant(ctor.variant_index_for_adt(*adt));
|
||||
@ -1402,7 +1406,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
&PatKind::Range(PatRange { lo, hi, end }) => {
|
||||
&PatKind::Range(box PatRange { lo, hi, end }) => {
|
||||
let ty = lo.ty();
|
||||
ctor = if let Some(int_range) = IntRange::from_range(
|
||||
cx.tcx,
|
||||
@ -1429,7 +1433,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
FixedLen(prefix.len() + suffix.len())
|
||||
};
|
||||
ctor = Slice(Slice::new(array_len, kind));
|
||||
fields = Fields::from_iter(cx, prefix.iter().chain(suffix).map(mkpat));
|
||||
fields =
|
||||
Fields::from_iter(cx, prefix.iter().chain(suffix.iter()).map(|p| mkpat(&*p)));
|
||||
}
|
||||
PatKind::Or { .. } => {
|
||||
ctor = Or;
|
||||
@ -1442,15 +1447,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
|
||||
pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'tcx> {
|
||||
let is_wildcard = |pat: &Pat<'_>| {
|
||||
matches!(*pat.kind, PatKind::Binding { subpattern: None, .. } | PatKind::Wild)
|
||||
matches!(pat.kind, PatKind::Binding { subpattern: None, .. } | PatKind::Wild)
|
||||
};
|
||||
let mut subpatterns = self.iter_fields().map(|p| p.to_pat(cx));
|
||||
let pat = match &self.ctor {
|
||||
let mut subpatterns = self.iter_fields().map(|p| Box::new(p.to_pat(cx)));
|
||||
let kind = match &self.ctor {
|
||||
Single | Variant(_) => match self.ty.kind() {
|
||||
ty::Tuple(..) => PatKind::Leaf {
|
||||
subpatterns: subpatterns
|
||||
.enumerate()
|
||||
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p })
|
||||
.map(|(i, pattern)| FieldPat { field: Field::new(i), pattern })
|
||||
.collect(),
|
||||
},
|
||||
ty::Adt(adt_def, _) if adt_def.is_box() => {
|
||||
@ -1485,7 +1490,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
FixedLen(_) => PatKind::Slice {
|
||||
prefix: subpatterns.collect(),
|
||||
slice: None,
|
||||
suffix: vec![],
|
||||
suffix: Box::new([]),
|
||||
},
|
||||
VarLen(prefix, _) => {
|
||||
let mut subpatterns = subpatterns.peekable();
|
||||
@ -1504,14 +1509,18 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
subpatterns.next();
|
||||
}
|
||||
}
|
||||
let suffix: Vec<_> = subpatterns.collect();
|
||||
let suffix: Box<[_]> = subpatterns.collect();
|
||||
let wild = Pat::wildcard_from_ty(self.ty);
|
||||
PatKind::Slice { prefix, slice: Some(wild), suffix }
|
||||
PatKind::Slice {
|
||||
prefix: prefix.into_boxed_slice(),
|
||||
slice: Some(Box::new(wild)),
|
||||
suffix,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&Str(value) => PatKind::Constant { value },
|
||||
&FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
|
||||
&FloatRange(lo, hi, end) => PatKind::Range(Box::new(PatRange { lo, hi, end })),
|
||||
IntRange(range) => return range.to_pat(cx.tcx, self.ty),
|
||||
Wildcard | NonExhaustive => PatKind::Wild,
|
||||
Missing { .. } => bug!(
|
||||
@ -1523,7 +1532,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
Pat { ty: self.ty, span: DUMMY_SP, kind: Box::new(pat) }
|
||||
Pat { ty: self.ty, span: DUMMY_SP, kind }
|
||||
}
|
||||
|
||||
pub(super) fn is_or_pat(&self) -> bool {
|
||||
|
@ -49,7 +49,7 @@ pub(crate) fn pat_from_hir<'a, 'tcx>(
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
) -> Pat<'tcx> {
|
||||
) -> Box<Pat<'tcx>> {
|
||||
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results);
|
||||
let result = pcx.lower_pattern(pat);
|
||||
if !pcx.errors.is_empty() {
|
||||
@ -74,7 +74,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
|
||||
pub(crate) fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
|
||||
// pattern has the type that results *after* dereferencing. For example, in this code:
|
||||
//
|
||||
@ -97,13 +97,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
let unadjusted_pat = self.lower_pattern_unadjusted(pat);
|
||||
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
|
||||
unadjusted_pat,
|
||||
|pat, ref_ty| {
|
||||
|pat: Box<_>, ref_ty| {
|
||||
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
|
||||
Pat {
|
||||
Box::new(Pat {
|
||||
span: pat.span,
|
||||
ty: *ref_ty,
|
||||
kind: Box::new(PatKind::Deref { subpattern: pat }),
|
||||
}
|
||||
kind: PatKind::Deref { subpattern: pat },
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -113,7 +113,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> (PatKind<'tcx>, Option<Ascription<'tcx>>) {
|
||||
match self.lower_lit(expr) {
|
||||
PatKind::AscribeUserType { ascription, subpattern: Pat { kind: box kind, .. } } => {
|
||||
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
|
||||
(kind, Some(ascription))
|
||||
}
|
||||
kind => (kind, None),
|
||||
@ -134,7 +134,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
match (end, cmp) {
|
||||
// `x..y` where `x < y`.
|
||||
// Non-empty because the range includes at least `x`.
|
||||
(RangeEnd::Excluded, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
|
||||
(RangeEnd::Excluded, Some(Ordering::Less)) => {
|
||||
PatKind::Range(Box::new(PatRange { lo, hi, end }))
|
||||
}
|
||||
// `x..y` where `x >= y`. The range is empty => error.
|
||||
(RangeEnd::Excluded, _) => {
|
||||
struct_span_err!(
|
||||
@ -149,7 +151,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
// `x..=y` where `x == y`.
|
||||
(RangeEnd::Included, Some(Ordering::Equal)) => PatKind::Constant { value: lo },
|
||||
// `x..=y` where `x < y`.
|
||||
(RangeEnd::Included, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
|
||||
(RangeEnd::Included, Some(Ordering::Less)) => {
|
||||
PatKind::Range(Box::new(PatRange { lo, hi, end }))
|
||||
}
|
||||
// `x..=y` where `x > y` hence the range is empty => error.
|
||||
(RangeEnd::Included, _) => {
|
||||
let mut err = struct_span_err!(
|
||||
@ -196,7 +200,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> {
|
||||
fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||
let mut ty = self.typeck_results.node_type(pat.hir_id);
|
||||
|
||||
let kind = match pat.kind {
|
||||
@ -228,7 +232,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
// constants somewhere. Have them on the range pattern.
|
||||
for end in &[lo, hi] {
|
||||
if let Some((_, Some(ascription))) = end {
|
||||
let subpattern = Pat { span: pat.span, ty, kind: Box::new(kind) };
|
||||
let subpattern = Box::new(Pat { span: pat.span, ty, kind });
|
||||
kind =
|
||||
PatKind::AscribeUserType { ascription: ascription.clone(), subpattern };
|
||||
}
|
||||
@ -322,7 +326,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) },
|
||||
};
|
||||
|
||||
Pat { span: pat.span, ty, kind: Box::new(kind) }
|
||||
Box::new(Pat { span: pat.span, ty, kind })
|
||||
}
|
||||
|
||||
fn lower_tuple_subpats(
|
||||
@ -340,11 +344,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> {
|
||||
fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Box<[Box<Pat<'tcx>>]> {
|
||||
pats.iter().map(|p| self.lower_pattern(p)).collect()
|
||||
}
|
||||
|
||||
fn lower_opt_pattern(&mut self, pat: &'tcx Option<&'tcx hir::Pat<'tcx>>) -> Option<Pat<'tcx>> {
|
||||
fn lower_opt_pattern(
|
||||
&mut self,
|
||||
pat: &'tcx Option<&'tcx hir::Pat<'tcx>>,
|
||||
) -> Option<Box<Pat<'tcx>>> {
|
||||
pat.as_ref().map(|p| self.lower_pattern(p))
|
||||
}
|
||||
|
||||
@ -436,12 +443,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) {
|
||||
debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span);
|
||||
let annotation = CanonicalUserTypeAnnotation {
|
||||
user_ty,
|
||||
user_ty: Box::new(user_ty),
|
||||
span,
|
||||
inferred_ty: self.typeck_results.node_type(hir_id),
|
||||
};
|
||||
kind = PatKind::AscribeUserType {
|
||||
subpattern: Pat { span, ty, kind: Box::new(kind) },
|
||||
subpattern: Box::new(Pat { span, ty, kind }),
|
||||
ascription: Ascription { annotation, variance: ty::Variance::Covariant },
|
||||
};
|
||||
}
|
||||
@ -453,11 +460,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
/// it to `const_to_pat`. Any other path (like enum variants without fields)
|
||||
/// is converted to the corresponding pattern via `lower_variant_or_leaf`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Pat<'tcx> {
|
||||
fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) -> Box<Pat<'tcx>> {
|
||||
let ty = self.typeck_results.node_type(id);
|
||||
let res = self.typeck_results.qpath_res(qpath, id);
|
||||
|
||||
let pat_from_kind = |kind| Pat { span, ty, kind: Box::new(kind) };
|
||||
let pat_from_kind = |kind| Box::new(Pat { span, ty, kind });
|
||||
|
||||
let (def_id, is_associated_const) = match res {
|
||||
Res::Def(DefKind::Const, def_id) => (def_id, false),
|
||||
@ -505,13 +512,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
let user_provided_types = self.typeck_results().user_provided_types();
|
||||
if let Some(&user_ty) = user_provided_types.get(id) {
|
||||
let annotation = CanonicalUserTypeAnnotation {
|
||||
user_ty,
|
||||
user_ty: Box::new(user_ty),
|
||||
span,
|
||||
inferred_ty: self.typeck_results().node_type(id),
|
||||
};
|
||||
Pat {
|
||||
Box::new(Pat {
|
||||
span,
|
||||
kind: Box::new(PatKind::AscribeUserType {
|
||||
kind: PatKind::AscribeUserType {
|
||||
subpattern: pattern,
|
||||
ascription: Ascription {
|
||||
annotation,
|
||||
@ -519,9 +526,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
/// `variance` field documentation for details.
|
||||
variance: ty::Variance::Contravariant,
|
||||
},
|
||||
}),
|
||||
},
|
||||
ty: const_.ty(),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
pattern
|
||||
}
|
||||
@ -569,7 +576,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
_ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"),
|
||||
}
|
||||
}
|
||||
mir::ConstantKind::Val(_, _) => *self.const_to_pat(value, id, span, false).kind,
|
||||
mir::ConstantKind::Val(_, _) => self.const_to_pat(value, id, span, false).kind,
|
||||
}
|
||||
}
|
||||
|
||||
@ -580,7 +587,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
|
||||
let (lit, neg) = match expr.kind {
|
||||
hir::ExprKind::Path(ref qpath) => {
|
||||
return *self.lower_path(qpath, expr.hir_id, expr.span).kind;
|
||||
return self.lower_path(qpath, expr.hir_id, expr.span).kind;
|
||||
}
|
||||
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||
return self.lower_inline_const(anon_const, expr.hir_id, expr.span);
|
||||
@ -598,7 +605,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
let lit_input =
|
||||
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
|
||||
match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) {
|
||||
Ok(constant) => *self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
|
||||
Ok(constant) => self.const_to_pat(constant, expr.hir_id, lit.span, false).kind,
|
||||
Err(LitToConstError::Reported) => PatKind::Wild,
|
||||
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
|
||||
}
|
||||
@ -646,6 +653,12 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Box<[T]> {
|
||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
self.iter().map(|t| t.fold_with(folder)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> {
|
||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
self.as_ref().map(|t| t.fold_with(folder))
|
||||
@ -732,7 +745,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
|
||||
PatKind::Deref { subpattern: subpattern.fold_with(folder) }
|
||||
}
|
||||
PatKind::Constant { value } => PatKind::Constant { value },
|
||||
PatKind::Range(range) => PatKind::Range(range),
|
||||
PatKind::Range(ref range) => PatKind::Range(range.clone()),
|
||||
PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {
|
||||
prefix: prefix.fold_with(folder),
|
||||
slice: slice.fold_with(folder),
|
||||
|
@ -155,9 +155,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
||||
return true;
|
||||
}
|
||||
|
||||
match pat.kind.as_ref() {
|
||||
match pat.kind {
|
||||
thir::PatKind::Constant { value } => value.has_param_types_or_consts(),
|
||||
thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => {
|
||||
thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
|
||||
lo.has_param_types_or_consts() || hi.has_param_types_or_consts()
|
||||
}
|
||||
_ => false,
|
||||
|
Loading…
Reference in New Issue
Block a user