@@ -499,7 +499,7 @@ use crate::errors::{
499
499
500
500
use rustc_data_structures:: captures:: Captures ;
501
501
502
- use rustc_arena:: TypedArena ;
502
+ use rustc_arena:: { DroplessArena , TypedArena } ;
503
503
use rustc_data_structures:: stack:: ensure_sufficient_stack;
504
504
use rustc_hir:: def_id:: DefId ;
505
505
use rustc_hir:: HirId ;
@@ -508,8 +508,8 @@ use rustc_session::lint;
508
508
use rustc_session:: lint:: builtin:: NON_EXHAUSTIVE_OMITTED_PATTERNS ;
509
509
use rustc_span:: { Span , DUMMY_SP } ;
510
510
511
- use smallvec:: { smallvec , SmallVec } ;
512
- use std:: fmt;
511
+ use smallvec:: SmallVec ;
512
+ use std:: { fmt, iter :: once } ;
513
513
514
514
pub ( crate ) struct MatchCheckCtxt < ' p , ' tcx > {
515
515
pub ( crate ) tcx : TyCtxt < ' tcx > ,
@@ -521,6 +521,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
521
521
pub ( crate ) module : DefId ,
522
522
pub ( crate ) param_env : ty:: ParamEnv < ' tcx > ,
523
523
pub ( crate ) pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , ' tcx > > ,
524
+ pub ( crate ) dropless_arena : & ' p DroplessArena ,
524
525
/// Lint level at the match.
525
526
pub ( crate ) match_lint_level : HirId ,
526
527
/// The span of the whole match, if applicable.
@@ -570,13 +571,12 @@ impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
570
571
/// Represents a pattern-tuple under investigation.
571
572
#[ derive( Clone ) ]
572
573
struct PatStack < ' p , ' tcx > {
573
- // Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
574
- pats : SmallVec < [ & ' p DeconstructedPat < ' p , ' tcx > ; 2 ] > ,
574
+ pats : & ' p [ & ' p DeconstructedPat < ' p , ' tcx > ] ,
575
575
}
576
576
577
577
impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
578
- fn from_pattern ( pat : & ' p DeconstructedPat < ' p , ' tcx > ) -> Self {
579
- PatStack { pats : smallvec ! [ pat] }
578
+ fn from_pattern ( cx : & MatchCheckCtxt < ' p , ' _ > , pat : & ' p DeconstructedPat < ' p , ' tcx > ) -> Self {
579
+ PatStack { pats : cx . dropless_arena . alloc_from_iter ( once ( pat) ) }
580
580
}
581
581
582
582
fn is_empty ( & self ) -> bool {
@@ -597,12 +597,14 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
597
597
598
598
// Recursively expand the first or-pattern into its subpatterns. Only useful if the pattern is
599
599
// an or-pattern. Panics if `self` is empty.
600
- fn expand_or_pat < ' a > ( & ' a self ) -> impl Iterator < Item = PatStack < ' p , ' tcx > > + Captures < ' a > {
601
- self . head ( ) . flatten_or_pat ( ) . into_iter ( ) . map ( move |pat| {
602
- let mut new_pats = SmallVec :: < [ _ ; 2 ] > :: with_capacity ( self . len ( ) ) ;
603
- new_pats. push ( pat) ;
604
- new_pats. extend_from_slice ( & self . pats [ 1 ..] ) ;
605
- PatStack { pats : new_pats }
600
+ fn expand_or_pat < ' a > (
601
+ & ' a self ,
602
+ cx : & ' a MatchCheckCtxt < ' p , ' tcx > ,
603
+ ) -> impl Iterator < Item = PatStack < ' p , ' tcx > > + Captures < ' a > {
604
+ self . head ( ) . flatten_or_pat ( ) . into_iter ( ) . map ( move |pat| PatStack {
605
+ pats : cx
606
+ . dropless_arena
607
+ . alloc_from_iter ( once ( pat) . chain ( self . pats [ 1 ..] . iter ( ) . copied ( ) ) ) ,
606
608
} )
607
609
}
608
610
@@ -616,10 +618,12 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
616
618
// We pop the head pattern and push the new fields extracted from the arguments of
617
619
// `self.head()`.
618
620
let ctor_fields = self . head ( ) . specialize ( pcx, ctor) ;
619
- let mut new_pats = SmallVec :: < [ _ ; 2 ] > :: with_capacity ( self . len ( ) + ctor_fields. len ( ) - 1 ) ;
620
- new_pats. extend_from_slice ( & ctor_fields) ;
621
- new_pats. extend_from_slice ( & self . pats [ 1 ..] ) ;
622
- PatStack { pats : new_pats }
621
+ PatStack {
622
+ pats : pcx
623
+ . cx
624
+ . dropless_arena
625
+ . alloc_from_iter ( ctor_fields. into_iter ( ) . chain ( self . pats [ 1 ..] . iter ( ) . copied ( ) ) ) ,
626
+ }
623
627
}
624
628
}
625
629
@@ -670,8 +674,11 @@ impl<'p, 'tcx> MatrixRow<'p, 'tcx> {
670
674
671
675
// Recursively expand the first or-pattern into its subpatterns. Only useful if the pattern is
672
676
// an or-pattern. Panics if `self` is empty.
673
- fn expand_or_pat < ' a > ( & ' a self ) -> impl Iterator < Item = MatrixRow < ' p , ' tcx > > + Captures < ' a > {
674
- self . pats . expand_or_pat ( ) . map ( |patstack| MatrixRow {
677
+ fn expand_or_pat < ' a > (
678
+ & ' a self ,
679
+ cx : & ' a MatchCheckCtxt < ' p , ' tcx > ,
680
+ ) -> impl Iterator < Item = MatrixRow < ' p , ' tcx > > + Captures < ' a > {
681
+ self . pats . expand_or_pat ( cx) . map ( |patstack| MatrixRow {
675
682
pats : patstack,
676
683
parent_row : self . parent_row ,
677
684
is_under_guard : self . is_under_guard ,
@@ -723,10 +730,10 @@ struct Matrix<'p, 'tcx> {
723
730
impl < ' p , ' tcx > Matrix < ' p , ' tcx > {
724
731
/// Pushes a new row to the matrix. If the row starts with an or-pattern, this recursively
725
732
/// expands it. Internal method, prefer [`Matrix::new`].
726
- fn expand_and_push ( & mut self , row : MatrixRow < ' p , ' tcx > ) {
733
+ fn expand_and_push ( & mut self , cx : & MatchCheckCtxt < ' p , ' tcx > , row : MatrixRow < ' p , ' tcx > ) {
727
734
if !row. is_empty ( ) && row. head ( ) . is_or_pat ( ) {
728
735
// Expand nested or-patterns.
729
- for new_row in row. expand_or_pat ( ) {
736
+ for new_row in row. expand_or_pat ( cx ) {
730
737
self . rows . push ( new_row) ;
731
738
}
732
739
} else {
@@ -737,16 +744,16 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
737
744
/// Build a new matrix from an iterator of `MatchArm`s.
738
745
fn new ( cx : & MatchCheckCtxt < ' p , ' tcx > , arms : & [ MatchArm < ' p , ' tcx > ] , scrut_ty : Ty < ' tcx > ) -> Self {
739
746
let wild_pattern = cx. pattern_arena . alloc ( DeconstructedPat :: wildcard ( scrut_ty, DUMMY_SP ) ) ;
740
- let wildcard_row = PatStack :: from_pattern ( wild_pattern) ;
747
+ let wildcard_row = PatStack :: from_pattern ( cx , wild_pattern) ;
741
748
let mut matrix = Matrix { rows : Vec :: with_capacity ( arms. len ( ) ) , wildcard_row } ;
742
749
for ( row_id, arm) in arms. iter ( ) . enumerate ( ) {
743
750
let v = MatrixRow {
744
- pats : PatStack :: from_pattern ( arm. pat ) ,
751
+ pats : PatStack :: from_pattern ( cx , arm. pat ) ,
745
752
parent_row : row_id, // dummy, we won't read it
746
753
is_under_guard : arm. has_guard ,
747
754
reachable : false ,
748
755
} ;
749
- matrix. expand_and_push ( v) ;
756
+ matrix. expand_and_push ( cx , v) ;
750
757
}
751
758
matrix
752
759
}
@@ -807,7 +814,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
807
814
for ( i, row) in self . rows ( ) . enumerate ( ) {
808
815
if ctor. is_covered_by ( pcx, row. head ( ) . ctor ( ) ) {
809
816
let new_row = row. pop_head_constructor ( pcx, ctor, i) ;
810
- matrix. expand_and_push ( new_row) ;
817
+ matrix. expand_and_push ( pcx . cx , new_row) ;
811
818
}
812
819
}
813
820
matrix
0 commit comments