1
Fork 0

Clean up THIR patterns.

`thir::Pat::kind` is a `Box<PatKind>`, which doesn't follow the usual
pattern in AST/HIR/THIR which is that the "kind" enum for a node is
stored inline within the parent struct.

This commit makes the `PatKind` directly inline within the `Pat`. This
requires using `Box<Pat>` in all the types that hold a `Pat.

Ideally, `Pat` would be stored in `Thir` like `Expr` and `Stmt` and
referred to with a `PatId` rather than `Box<Pat>`. But this is hard to
do because lots of `Pat`s get created after the destruction of the `Cx`
that does normal THIR building. But this does get us a step closer to
`PatId`, because all the `Box<Pat>` occurrences would be replaced with
`PatId` if `PatId` ever happened.

At 128 bytes, `Pat` is large. Subsequent commits will shrink it.
This commit is contained in:
Nicholas Nethercote 2022-08-25 12:25:44 +10:00
parent 9af618b62e
commit 053874eecc
15 changed files with 123 additions and 121 deletions

View file

@ -180,7 +180,7 @@ pub enum StmtKind<'tcx> {
/// `let <PAT> = ...` /// `let <PAT> = ...`
/// ///
/// If a type annotation is included, it is added as an ascription pattern. /// If a type annotation is included, it is added as an ascription pattern.
pattern: Pat<'tcx>, pattern: Box<Pat<'tcx>>,
/// `let pat: ty = <INIT>` /// `let pat: ty = <INIT>`
initializer: Option<ExprId>, initializer: Option<ExprId>,
@ -301,7 +301,7 @@ pub enum ExprKind<'tcx> {
}, },
Let { Let {
expr: ExprId, expr: ExprId,
pat: Pat<'tcx>, pat: Box<Pat<'tcx>>,
}, },
/// A `match` expression. /// A `match` expression.
Match { Match {
@ -467,7 +467,7 @@ pub struct FruInfo<'tcx> {
/// A `match` arm. /// A `match` arm.
#[derive(Clone, Debug, HashStable)] #[derive(Clone, Debug, HashStable)]
pub struct Arm<'tcx> { pub struct Arm<'tcx> {
pub pattern: Pat<'tcx>, pub pattern: Box<Pat<'tcx>>,
pub guard: Option<Guard<'tcx>>, pub guard: Option<Guard<'tcx>>,
pub body: ExprId, pub body: ExprId,
pub lint_level: LintLevel, pub lint_level: LintLevel,
@ -479,7 +479,7 @@ pub struct Arm<'tcx> {
#[derive(Clone, Debug, HashStable)] #[derive(Clone, Debug, HashStable)]
pub enum Guard<'tcx> { pub enum Guard<'tcx> {
If(ExprId), If(ExprId),
IfLet(Pat<'tcx>, ExprId), IfLet(Box<Pat<'tcx>>, ExprId),
} }
#[derive(Copy, Clone, Debug, HashStable)] #[derive(Copy, Clone, Debug, HashStable)]
@ -534,19 +534,19 @@ pub enum BindingMode {
#[derive(Clone, Debug, HashStable)] #[derive(Clone, Debug, HashStable)]
pub struct FieldPat<'tcx> { pub struct FieldPat<'tcx> {
pub field: Field, pub field: Field,
pub pattern: Pat<'tcx>, pub pattern: Box<Pat<'tcx>>,
} }
#[derive(Clone, Debug, HashStable)] #[derive(Clone, Debug, HashStable)]
pub struct Pat<'tcx> { pub struct Pat<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
pub span: Span, pub span: Span,
pub kind: Box<PatKind<'tcx>>, pub kind: PatKind<'tcx>,
} }
impl<'tcx> Pat<'tcx> { impl<'tcx> Pat<'tcx> {
pub fn wildcard_from_ty(ty: Ty<'tcx>) -> Self { 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 { AscribeUserType {
ascription: Ascription<'tcx>, ascription: Ascription<'tcx>,
subpattern: Pat<'tcx>, subpattern: Box<Pat<'tcx>>,
}, },
/// `x`, `ref x`, `x @ P`, etc. /// `x`, `ref x`, `x @ P`, etc.
@ -591,7 +591,7 @@ pub enum PatKind<'tcx> {
mode: BindingMode, mode: BindingMode,
var: LocalVarId, var: LocalVarId,
ty: Ty<'tcx>, 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 /// Is this the leftmost occurrence of the binding, i.e., is `var` the
/// `HirId` of this pattern? /// `HirId` of this pattern?
is_primary: bool, is_primary: bool,
@ -614,7 +614,7 @@ pub enum PatKind<'tcx> {
/// `box P`, `&P`, `&mut P`, etc. /// `box P`, `&P`, `&mut P`, etc.
Deref { Deref {
subpattern: Pat<'tcx>, subpattern: Box<Pat<'tcx>>,
}, },
/// One of the following: /// One of the following:
@ -634,22 +634,22 @@ pub enum PatKind<'tcx> {
/// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty. /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
/// e.g., `&[ref xs @ ..]`. /// e.g., `&[ref xs @ ..]`.
Slice { Slice {
prefix: Vec<Pat<'tcx>>, prefix: Vec<Box<Pat<'tcx>>>,
slice: Option<Pat<'tcx>>, slice: Option<Box<Pat<'tcx>>>,
suffix: Vec<Pat<'tcx>>, suffix: Vec<Box<Pat<'tcx>>>,
}, },
/// Fixed match against an array; irrefutable. /// Fixed match against an array; irrefutable.
Array { Array {
prefix: Vec<Pat<'tcx>>, prefix: Vec<Box<Pat<'tcx>>>,
slice: Option<Pat<'tcx>>, slice: Option<Box<Pat<'tcx>>>,
suffix: Vec<Pat<'tcx>>, suffix: Vec<Box<Pat<'tcx>>>,
}, },
/// An or-pattern, e.g. `p | q`. /// An or-pattern, e.g. `p | q`.
/// Invariant: `pats.len() >= 2`. /// Invariant: `pats.len() >= 2`.
Or { Or {
pats: Vec<Pat<'tcx>>, pats: Vec<Box<Pat<'tcx>>>,
}, },
} }
@ -674,7 +674,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
}; };
let mut start_or_comma = || start_or_continue(", "); let mut start_or_comma = || start_or_continue(", ");
match *self.kind { match self.kind {
PatKind::Wild => write!(f, "_"), PatKind::Wild => write!(f, "_"),
PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern), PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern),
PatKind::Binding { mutability, name, mode, ref subpattern, .. } => { PatKind::Binding { mutability, name, mode, ref subpattern, .. } => {
@ -695,7 +695,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
Ok(()) Ok(())
} }
PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => { PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => {
let variant = match *self.kind { let variant = match self.kind {
PatKind::Variant { adt_def, variant_index, .. } => { PatKind::Variant { adt_def, variant_index, .. } => {
Some(adt_def.variant(variant_index)) Some(adt_def.variant(variant_index))
} }
@ -714,7 +714,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
let mut printed = 0; let mut printed = 0;
for p in subpatterns { for p in subpatterns {
if let PatKind::Wild = *p.pattern.kind { if let PatKind::Wild = p.pattern.kind {
continue; continue;
} }
let name = variant.fields[p.field.index()].name; let name = variant.fields[p.field.index()].name;
@ -780,7 +780,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
} }
if let Some(ref slice) = *slice { if let Some(ref slice) = *slice {
write!(f, "{}", start_or_comma())?; write!(f, "{}", start_or_comma())?;
match *slice.kind { match slice.kind {
PatKind::Wild => {} PatKind::Wild => {}
_ => write!(f, "{}", slice)?, _ => write!(f, "{}", slice)?,
} }
@ -809,8 +809,8 @@ mod size_asserts {
static_assert_size!(Block, 56); static_assert_size!(Block, 56);
static_assert_size!(Expr<'_>, 64); static_assert_size!(Expr<'_>, 64);
static_assert_size!(ExprKind<'_>, 40); static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 24); static_assert_size!(Pat<'_>, 128);
static_assert_size!(PatKind<'_>, 112); static_assert_size!(PatKind<'_>, 112);
static_assert_size!(Stmt<'_>, 72); static_assert_size!(Stmt<'_>, 56);
static_assert_size!(StmtKind<'_>, 64); static_assert_size!(StmtKind<'_>, 48);
} }

View file

@ -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>) { pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
use PatKind::*; use PatKind::*;
match pat.kind.as_ref() { match &pat.kind {
AscribeUserType { subpattern, ascription: _ } AscribeUserType { subpattern, ascription: _ }
| Deref { subpattern } | Deref { subpattern }
| Binding { | Binding {
@ -236,7 +236,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
visitor.visit_pat(&subpattern); visitor.visit_pat(&subpattern);
} }
if let Some(pat) = slice { if let Some(pat) = slice {
visitor.visit_pat(pat); visitor.visit_pat(&pat);
} }
for subpattern in suffix { for subpattern in suffix {
visitor.visit_pat(&subpattern); visitor.visit_pat(&subpattern);

View file

@ -117,7 +117,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
lint_level, lint_level,
else_block, 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 }); this.block_context.push(BlockFrame::Statement { ignores_expr_result });
// Enter the remainder scope, i.e., the bindings' destruction scope. // Enter the remainder scope, i.e., the bindings' destruction scope.
@ -160,7 +160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ArmHasGuard(false), ArmHasGuard(false),
Some((None, initializer_span)), Some((None, initializer_span)),
); );
this.expr_into_pattern(block, pattern.clone(), init) // irrefutable pattern this.expr_into_pattern(block, (**pattern).clone(), init) // irrefutable pattern
} }
}) })
}, },

View file

@ -493,7 +493,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
irrefutable_pat: Pat<'tcx>, irrefutable_pat: Pat<'tcx>,
initializer: &Expr<'tcx>, initializer: &Expr<'tcx>,
) -> BlockAnd<()> { ) -> BlockAnd<()> {
match *irrefutable_pat.kind { match irrefutable_pat.kind {
// Optimize the case of `let x = ...` to write directly into `x` // Optimize the case of `let x = ...` to write directly into `x`
PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => { PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
let place = let place =
@ -518,13 +518,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// broken. // broken.
PatKind::AscribeUserType { PatKind::AscribeUserType {
subpattern: subpattern:
Pat { box Pat {
kind: kind:
box PatKind::Binding { PatKind::Binding {
mode: BindingMode::ByValue, mode: BindingMode::ByValue, var, subpattern: None, ..
var,
subpattern: None,
..
}, },
.. ..
}, },
@ -744,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
"visit_primary_bindings: pattern={:?} pattern_user_ty={:?}", "visit_primary_bindings: pattern={:?} pattern_user_ty={:?}",
pattern, pattern_user_ty pattern, pattern_user_ty
); );
match *pattern.kind { match pattern.kind {
PatKind::Binding { PatKind::Binding {
mutability, mutability,
name, name,
@ -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 // 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. // 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 { .. } => (), PatKind::Or { .. } => (),
_ => { _ => {
self.test_candidates( self.test_candidates(
@ -1350,7 +1347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let mut otherwise = None; let mut otherwise = None;
for match_pair in match_pairs { 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"); bug!("Or-patterns should have been sorted to the end");
}; };
let or_span = match_pair.pattern.span; let or_span = match_pair.pattern.span;
@ -1384,7 +1381,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self, &mut self,
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
otherwise: &mut Option<BasicBlock>, otherwise: &mut Option<BasicBlock>,
pats: &'pat [Pat<'tcx>], pats: &'pat [Box<Pat<'tcx>>],
or_span: Span, or_span: Span,
place: PlaceBuilder<'tcx>, place: PlaceBuilder<'tcx>,
fake_borrows: &mut Option<FxIndexSet<Place<'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 else_block_span = self.thir[else_block].span;
let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| { let (matching, failure) = self.in_if_then_scope(remainder_scope, |this| {
let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span)); 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); let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false);
this.declare_bindings( this.declare_bindings(
visibility_scope, visibility_scope,

View file

@ -67,7 +67,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
loop { loop {
let match_pairs = mem::take(&mut candidate.match_pairs); 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 &*match_pairs
{ {
existing_bindings.extend_from_slice(&new_bindings); existing_bindings.extend_from_slice(&new_bindings);
@ -113,7 +113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// late as possible. // late as possible.
candidate candidate
.match_pairs .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"); debug!(simplified = ?candidate, "simplify_candidate");
return false; // if we were not able to simplify any, done. return false; // if we were not able to simplify any, done.
} }
@ -127,10 +127,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self, &mut self,
candidate: &Candidate<'pat, 'tcx>, candidate: &Candidate<'pat, 'tcx>,
place: PlaceBuilder<'tcx>, place: PlaceBuilder<'tcx>,
pats: &'pat [Pat<'tcx>], pats: &'pat [Box<Pat<'tcx>>],
) -> Vec<Candidate<'pat, 'tcx>> { ) -> Vec<Candidate<'pat, 'tcx>> {
pats.iter() pats.iter()
.map(|pat| { .map(|box pat| {
let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard); let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard);
self.simplify_candidate(&mut candidate); self.simplify_candidate(&mut candidate);
candidate candidate
@ -149,7 +149,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
) -> Result<(), MatchPair<'pat, 'tcx>> { ) -> Result<(), MatchPair<'pat, 'tcx>> {
let tcx = self.tcx; let tcx = self.tcx;
match *match_pair.pattern.kind { match match_pair.pattern.kind {
PatKind::AscribeUserType { PatKind::AscribeUserType {
ref subpattern, ref subpattern,
ascription: thir::Ascription { ref annotation, variance }, ascription: thir::Ascription { ref annotation, variance },
@ -254,7 +254,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut candidate.match_pairs, &mut candidate.match_pairs,
&match_pair.place, &match_pair.place,
prefix, prefix,
slice.as_ref(), slice,
suffix, suffix,
); );
Ok(()) Ok(())
@ -294,7 +294,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut candidate.match_pairs, &mut candidate.match_pairs,
&match_pair.place, &match_pair.place,
prefix, prefix,
slice.as_ref(), slice,
suffix, suffix,
); );
Ok(()) Ok(())

View file

@ -29,7 +29,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// ///
/// It is a bug to call this with a not-fully-simplified pattern. /// 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> { 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 { PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
span: match_pair.pattern.span, span: match_pair.pattern.span,
kind: TestKind::Switch { kind: TestKind::Switch {
@ -92,7 +92,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return false; return false;
}; };
match *match_pair.pattern.kind { match match_pair.pattern.kind {
PatKind::Constant { value } => { PatKind::Constant { value } => {
options options
.entry(value) .entry(value)
@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return false; return false;
}; };
match *match_pair.pattern.kind { match match_pair.pattern.kind {
PatKind::Variant { adt_def: _, variant_index, .. } => { PatKind::Variant { adt_def: _, variant_index, .. } => {
// We have a pattern testing for variant `variant_index` // We have a pattern testing for variant `variant_index`
// set the corresponding index to true // set the corresponding index to true
@ -506,7 +506,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let (match_pair_index, match_pair) = let (match_pair_index, match_pair) =
candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == *test_place)?; 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 // If we are performing a variant switch, then this
// informs variant patterns, but nothing else. // informs variant patterns, but nothing else.
( (
@ -569,7 +569,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pair_index, match_pair_index,
candidate, candidate,
prefix, prefix,
slice.as_ref(), slice,
suffix, suffix,
); );
Some(0) Some(0)
@ -607,7 +607,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match_pair_index, match_pair_index,
candidate, candidate,
prefix, prefix,
slice.as_ref(), slice,
suffix, suffix,
); );
Some(0) Some(0)
@ -678,7 +678,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// However, at this point we can still encounter or-patterns that were extracted // 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 // from previous calls to `sort_candidate`, so we need to manually address that
// case to avoid panicking in `self.test()`. // 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; return None;
} }
@ -708,9 +708,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self, &mut self,
match_pair_index: usize, match_pair_index: usize,
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
prefix: &'pat [Pat<'tcx>], prefix: &'pat [Box<Pat<'tcx>>],
opt_slice: Option<&'pat Pat<'tcx>>, opt_slice: &'pat Option<Box<Pat<'tcx>>>,
suffix: &'pat [Pat<'tcx>], suffix: &'pat [Box<Pat<'tcx>>],
) { ) {
let removed_place = candidate.match_pairs.remove(match_pair_index).place; let removed_place = candidate.match_pairs.remove(match_pair_index).place;
self.prefix_slice_suffix( self.prefix_slice_suffix(

View file

@ -26,9 +26,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self, &mut self,
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>, match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
place: &PlaceBuilder<'tcx>, place: &PlaceBuilder<'tcx>,
prefix: &'pat [Pat<'tcx>], prefix: &'pat [Box<Pat<'tcx>>],
opt_slice: Option<&'pat Pat<'tcx>>, opt_slice: &'pat Option<Box<Pat<'tcx>>>,
suffix: &'pat [Pat<'tcx>], suffix: &'pat [Box<Pat<'tcx>>],
) { ) {
let tcx = self.tcx; let tcx = self.tcx;
let (min_length, exact_size) = if let Ok(place_resolved) = let (min_length, exact_size) = if let Ok(place_resolved) =

View file

@ -1015,7 +1015,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let original_source_scope = self.source_scope; let original_source_scope = self.source_scope;
let span = pattern.span; let span = pattern.span;
self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, 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 // Don't introduce extra copies for simple bindings
PatKind::Binding { PatKind::Binding {
mutability, mutability,
@ -1052,7 +1052,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Some((Some(&place), span)), Some((Some(&place), span)),
); );
let place_builder = PlaceBuilder::from(local); 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, place_builder, false));
} }
} }
self.source_scope = original_source_scope; self.source_scope = original_source_scope;

View file

@ -214,7 +214,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
fn visit_pat(&mut self, pat: &Pat<'tcx>) { fn visit_pat(&mut self, pat: &Pat<'tcx>) {
if self.in_union_destructure { if self.in_union_destructure {
match *pat.kind { match pat.kind {
// binding to a variable allows getting stuff out of variable // binding to a variable allows getting stuff out of variable
PatKind::Binding { .. } PatKind::Binding { .. }
// match is conditional on having this value // 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 { .. } => { PatKind::Leaf { .. } => {
if let ty::Adt(adt_def, ..) = pat.ty.kind() { if let ty::Adt(adt_def, ..) = pat.ty.kind() {
if adt_def.is_union() { if adt_def.is_union() {

View file

@ -91,17 +91,17 @@ impl<'tcx> Cx<'tcx> {
span: ty.span, span: ty.span,
inferred_ty: self.typeck_results.node_type(ty.hir_id), inferred_ty: self.typeck_results.node_type(ty.hir_id),
}; };
pattern = Pat { pattern = Box::new(Pat {
ty: pattern.ty, ty: pattern.ty,
span: pattern.span, span: pattern.span,
kind: Box::new(PatKind::AscribeUserType { kind: PatKind::AscribeUserType {
ascription: Ascription { ascription: Ascription {
annotation, annotation,
variance: ty::Variance::Covariant, variance: ty::Variance::Covariant,
}, },
subpattern: pattern, subpattern: pattern,
}), },
}; });
} }
} }

View file

@ -78,7 +78,7 @@ impl<'tcx> Cx<'tcx> {
} }
#[instrument(level = "debug", skip(self))] #[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) { let p = match self.tcx.hir().get(p.hir_id) {
Node::Pat(p) => p, Node::Pat(p) => p,
node => bug!("pattern became {:?}", node), node => bug!("pattern became {:?}", node),

View file

@ -26,7 +26,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
id: hir::HirId, id: hir::HirId,
span: Span, span: Span,
mir_structural_match_violation: bool, mir_structural_match_violation: bool,
) -> Pat<'tcx> { ) -> Box<Pat<'tcx>> {
self.tcx.infer_ctxt().enter(|infcx| { self.tcx.infer_ctxt().enter(|infcx| {
let mut convert = ConstToPat::new(self, id, span, infcx); let mut convert = ConstToPat::new(self, id, span, infcx);
convert.to_pat(cv, mir_structural_match_violation) convert.to_pat(cv, mir_structural_match_violation)
@ -156,7 +156,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
&mut self, &mut self,
cv: mir::ConstantKind<'tcx>, cv: mir::ConstantKind<'tcx>,
mir_structural_match_violation: bool, mir_structural_match_violation: bool,
) -> Pat<'tcx> { ) -> Box<Pat<'tcx>> {
trace!(self.treat_byte_string_as_slice); trace!(self.treat_byte_string_as_slice);
// This method is just a wrapper handling a validity check; the heavy lifting is // 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 // 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 // level of indirection can be eliminated
let inlined_const_as_pat = let inlined_const_as_pat =
self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| Pat { self.recur(cv, mir_structural_match_violation).unwrap_or_else(|_| {
span: self.span, Box::new(Pat {
ty: cv.ty(), span: self.span,
kind: Box::new(PatKind::Constant { value: cv }), ty: cv.ty(),
kind: PatKind::Constant { value: cv },
})
}); });
if self.include_lint_checks && !self.saw_const_match_error.get() { if self.include_lint_checks && !self.saw_const_match_error.get() {
@ -271,7 +273,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
&self, &self,
cv: mir::ConstantKind<'tcx>, cv: mir::ConstantKind<'tcx>,
mir_structural_match_violation: bool, mir_structural_match_violation: bool,
) -> Result<Pat<'tcx>, FallbackToConstRef> { ) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
let id = self.id; let id = self.id;
let span = self.span; let span = self.span;
let tcx = self.tcx(); let tcx = self.tcx();
@ -425,8 +427,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let old = self.behind_reference.replace(true); let old = self.behind_reference.replace(true);
let array = tcx.deref_mir_constant(self.param_env.and(cv)); let array = tcx.deref_mir_constant(self.param_env.and(cv));
let val = PatKind::Deref { let val = PatKind::Deref {
subpattern: Pat { subpattern: Box::new(Pat {
kind: Box::new(PatKind::Array { kind: PatKind::Array {
prefix: tcx prefix: tcx
.destructure_mir_constant(param_env, array) .destructure_mir_constant(param_env, array)
.fields .fields
@ -435,10 +437,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
slice: None, slice: None,
suffix: vec![], suffix: vec![],
}), },
span, span,
ty: *pointee_ty, ty: *pointee_ty,
}, }),
}; };
self.behind_reference.set(old); self.behind_reference.set(old);
val val
@ -451,8 +453,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
let old = self.behind_reference.replace(true); let old = self.behind_reference.replace(true);
let array = tcx.deref_mir_constant(self.param_env.and(cv)); let array = tcx.deref_mir_constant(self.param_env.and(cv));
let val = PatKind::Deref { let val = PatKind::Deref {
subpattern: Pat { subpattern: Box::new(Pat {
kind: Box::new(PatKind::Slice { kind: PatKind::Slice {
prefix: tcx prefix: tcx
.destructure_mir_constant(param_env, array) .destructure_mir_constant(param_env, array)
.fields .fields
@ -461,10 +463,10 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
slice: None, slice: None,
suffix: vec![], suffix: vec![],
}), },
span, span,
ty: tcx.mk_slice(elem_ty), ty: tcx.mk_slice(elem_ty),
}, }),
}; };
self.behind_reference.set(old); self.behind_reference.set(old);
val 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 }))
} }
} }

View file

@ -71,9 +71,9 @@ use std::ops::RangeInclusive;
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns. /// 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_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>>) { fn expand<'p, 'tcx>(pat: &'p Pat<'tcx>, vec: &mut Vec<&'p Pat<'tcx>>) {
if let PatKind::Or { pats } = pat.kind.as_ref() { if let PatKind::Or { pats } = &pat.kind {
for pat in pats { for pat in pats {
expand(pat, vec); expand(&pat, vec);
} }
} else { } else {
vec.push(pat) vec.push(pat)
@ -255,7 +255,7 @@ impl IntRange {
PatKind::Range(PatRange { lo: lo_const, hi: hi_const, end: RangeEnd::Included }) PatKind::Range(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) /// Lint on likely incorrect range patterns (#63987)
@ -1297,7 +1297,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
let mkpat = |pat| DeconstructedPat::from_pat(cx, pat); let mkpat = |pat| DeconstructedPat::from_pat(cx, pat);
let ctor; let ctor;
let fields; let fields;
match pat.kind.as_ref() { match &pat.kind {
PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern), PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern),
PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat), PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat),
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => { PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
@ -1342,9 +1342,9 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
fields = Fields::singleton(cx, pat); fields = Fields::singleton(cx, pat);
} }
ty::Adt(adt, _) => { ty::Adt(adt, _) => {
ctor = match pat.kind.as_ref() { ctor = match pat.kind {
PatKind::Leaf { .. } => Single, PatKind::Leaf { .. } => Single,
PatKind::Variant { variant_index, .. } => Variant(*variant_index), PatKind::Variant { variant_index, .. } => Variant(variant_index),
_ => bug!(), _ => bug!(),
}; };
let variant = &adt.variant(ctor.variant_index_for_adt(*adt)); let variant = &adt.variant(ctor.variant_index_for_adt(*adt));
@ -1429,7 +1429,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
FixedLen(prefix.len() + suffix.len()) FixedLen(prefix.len() + suffix.len())
}; };
ctor = Slice(Slice::new(array_len, kind)); 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).map(|p| mkpat(&*p)));
} }
PatKind::Or { .. } => { PatKind::Or { .. } => {
ctor = Or; ctor = Or;
@ -1442,15 +1442,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'tcx> { pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'tcx> {
let is_wildcard = |pat: &Pat<'_>| { 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 mut subpatterns = self.iter_fields().map(|p| Box::new(p.to_pat(cx)));
let pat = match &self.ctor { let kind = match &self.ctor {
Single | Variant(_) => match self.ty.kind() { Single | Variant(_) => match self.ty.kind() {
ty::Tuple(..) => PatKind::Leaf { ty::Tuple(..) => PatKind::Leaf {
subpatterns: subpatterns subpatterns: subpatterns
.enumerate() .enumerate()
.map(|(i, p)| FieldPat { field: Field::new(i), pattern: p }) .map(|(i, pattern)| FieldPat { field: Field::new(i), pattern })
.collect(), .collect(),
}, },
ty::Adt(adt_def, _) if adt_def.is_box() => { ty::Adt(adt_def, _) if adt_def.is_box() => {
@ -1506,7 +1506,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
} }
let suffix: Vec<_> = subpatterns.collect(); let suffix: Vec<_> = subpatterns.collect();
let wild = Pat::wildcard_from_ty(self.ty); let wild = Pat::wildcard_from_ty(self.ty);
PatKind::Slice { prefix, slice: Some(wild), suffix } PatKind::Slice { prefix, slice: Some(Box::new(wild)), suffix }
} }
} }
} }
@ -1523,7 +1523,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 { pub(super) fn is_or_pat(&self) -> bool {

View file

@ -49,7 +49,7 @@ pub(crate) fn pat_from_hir<'a, 'tcx>(
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>,
pat: &'tcx hir::Pat<'tcx>, pat: &'tcx hir::Pat<'tcx>,
) -> Pat<'tcx> { ) -> Box<Pat<'tcx>> {
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results); let mut pcx = PatCtxt::new(tcx, param_env, typeck_results);
let result = pcx.lower_pattern(pat); let result = pcx.lower_pattern(pat);
if !pcx.errors.is_empty() { if !pcx.errors.is_empty() {
@ -74,7 +74,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
self 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 // 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: // 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); let unadjusted_pat = self.lower_pattern_unadjusted(pat);
self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold( self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
unadjusted_pat, unadjusted_pat,
|pat, ref_ty| { |pat: Box<_>, ref_ty| {
debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty); debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty);
Pat { Box::new(Pat {
span: pat.span, span: pat.span,
ty: *ref_ty, 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>, expr: &'tcx hir::Expr<'tcx>,
) -> (PatKind<'tcx>, Option<Ascription<'tcx>>) { ) -> (PatKind<'tcx>, Option<Ascription<'tcx>>) {
match self.lower_lit(expr) { match self.lower_lit(expr) {
PatKind::AscribeUserType { ascription, subpattern: Pat { kind: box kind, .. } } => { PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
(kind, Some(ascription)) (kind, Some(ascription))
} }
kind => (kind, None), kind => (kind, None),
@ -196,7 +196,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 mut ty = self.typeck_results.node_type(pat.hir_id);
let kind = match pat.kind { let kind = match pat.kind {
@ -228,7 +228,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// constants somewhere. Have them on the range pattern. // constants somewhere. Have them on the range pattern.
for end in &[lo, hi] { for end in &[lo, hi] {
if let Some((_, Some(ascription))) = end { 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 = kind =
PatKind::AscribeUserType { ascription: ascription.clone(), subpattern }; PatKind::AscribeUserType { ascription: ascription.clone(), subpattern };
} }
@ -322,7 +322,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) }, 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( fn lower_tuple_subpats(
@ -340,11 +340,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
.collect() .collect()
} }
fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Pat<'tcx>> { fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Vec<Box<Pat<'tcx>>> {
pats.iter().map(|p| self.lower_pattern(p)).collect() 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)) pat.as_ref().map(|p| self.lower_pattern(p))
} }
@ -441,7 +444,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
inferred_ty: self.typeck_results.node_type(hir_id), inferred_ty: self.typeck_results.node_type(hir_id),
}; };
kind = PatKind::AscribeUserType { 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 }, ascription: Ascription { annotation, variance: ty::Variance::Covariant },
}; };
} }
@ -453,11 +456,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// it to `const_to_pat`. Any other path (like enum variants without fields) /// it to `const_to_pat`. Any other path (like enum variants without fields)
/// is converted to the corresponding pattern via `lower_variant_or_leaf`. /// is converted to the corresponding pattern via `lower_variant_or_leaf`.
#[instrument(skip(self), level = "debug")] #[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 ty = self.typeck_results.node_type(id);
let res = self.typeck_results.qpath_res(qpath, 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 { let (def_id, is_associated_const) = match res {
Res::Def(DefKind::Const, def_id) => (def_id, false), Res::Def(DefKind::Const, def_id) => (def_id, false),
@ -509,9 +512,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
span, span,
inferred_ty: self.typeck_results().node_type(id), inferred_ty: self.typeck_results().node_type(id),
}; };
Pat { Box::new(Pat {
span, span,
kind: Box::new(PatKind::AscribeUserType { kind: PatKind::AscribeUserType {
subpattern: pattern, subpattern: pattern,
ascription: Ascription { ascription: Ascription {
annotation, annotation,
@ -519,9 +522,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// `variance` field documentation for details. /// `variance` field documentation for details.
variance: ty::Variance::Contravariant, variance: ty::Variance::Contravariant,
}, },
}), },
ty: const_.ty(), ty: const_.ty(),
} })
} else { } else {
pattern pattern
} }
@ -569,7 +572,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
_ => bug!("Expected either ConstKind::Param or ConstKind::Unevaluated"), _ => 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 +583,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> { fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
let (lit, neg) = match expr.kind { let (lit, neg) = match expr.kind {
hir::ExprKind::Path(ref qpath) => { 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) => { hir::ExprKind::ConstBlock(ref anon_const) => {
return self.lower_inline_const(anon_const, expr.hir_id, expr.span); return self.lower_inline_const(anon_const, expr.hir_id, expr.span);
@ -598,7 +601,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let lit_input = let lit_input =
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg }; LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
match self.tcx.at(expr.span).lit_to_mir_constant(lit_input) { 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::Reported) => PatKind::Wild,
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"), Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
} }

View file

@ -155,7 +155,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
return true; return true;
} }
match pat.kind.as_ref() { match pat.kind {
thir::PatKind::Constant { value } => value.has_param_types_or_consts(), thir::PatKind::Constant { value } => value.has_param_types_or_consts(),
thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => { thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => {
lo.has_param_types_or_consts() || hi.has_param_types_or_consts() lo.has_param_types_or_consts() || hi.has_param_types_or_consts()