@@ -1063,6 +1063,33 @@ pub(crate) struct Test<'tcx> {
10631063#[ derive( Copy , Clone , Debug ) ]
10641064pub ( crate ) struct ArmHasGuard ( pub ( crate ) bool ) ;
10651065
1066+ /// A single step in the match algorithm.
1067+ pub ( crate ) struct MatchAutomatonStep < ' a , ' c , ' pat , ' tcx > {
1068+ /// FIXME: probably the span of the match.
1069+ span : Span ,
1070+ /// Perform this test...
1071+ test : Test < ' tcx > ,
1072+ /// ... on this place...
1073+ place : PlaceBuilder < ' tcx > ,
1074+ /// ... depending on the result, branch to one of these candidate lists...
1075+ target_candidates : Vec < Vec < & ' a mut Candidate < ' pat , ' tcx > > > ,
1076+ /// ... if it doesn't match, continue with these...
1077+ remaining_candidates : & ' a mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
1078+ /// ... and if nothing matches, continue to this block.
1079+ otherwise_block : & ' a mut Option < BasicBlock > ,
1080+ /// Track places that need fake borrows.
1081+ fake_borrows : & ' a mut Option < FxIndexSet < Place < ' tcx > > > ,
1082+ }
1083+
1084+ impl < ' b , ' c , ' pat , ' tcx > std:: fmt:: Debug for MatchAutomatonStep < ' b , ' c , ' pat , ' tcx > {
1085+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
1086+ f. debug_struct ( "MatchAutomatonStep" )
1087+ . field ( "test" , & self . test )
1088+ . field ( "place" , & self . place )
1089+ . finish ( )
1090+ }
1091+ }
1092+
10661093///////////////////////////////////////////////////////////////////////////
10671094// Main matching algorithm
10681095
@@ -1699,59 +1726,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16991726 debug ! ( "tested_candidates: {}" , total_candidate_count - candidates. len( ) ) ;
17001727 debug ! ( "untested_candidates: {}" , candidates. len( ) ) ;
17011728
1702- // HACK(matthewjasper) This is a closure so that we can let the test
1703- // create its blocks before the rest of the match. This currently
1704- // improves the speed of llvm when optimizing long string literal
1705- // matches
1706- let make_target_blocks = move |this : & mut Self | -> Vec < BasicBlock > {
1707- // The block that we should branch to if none of the
1708- // `target_candidates` match. This is either the block where we
1709- // start matching the untested candidates if there are any,
1710- // otherwise it's the `otherwise_block`.
1711- let remainder_start = & mut None ;
1712- let remainder_start =
1713- if candidates. is_empty ( ) { & mut * otherwise_block } else { remainder_start } ;
1714-
1715- // For each outcome of test, process the candidates that still
1716- // apply. Collect a list of blocks where control flow will
1717- // branch if one of the `target_candidate` sets is not
1718- // exhaustive.
1719- let target_blocks: Vec < _ > = target_candidates
1720- . into_iter ( )
1721- . map ( |mut candidates| {
1722- if !candidates. is_empty ( ) {
1723- let candidate_start = this. cfg . start_new_block ( ) ;
1724- this. match_candidates (
1725- span,
1726- scrutinee_span,
1727- candidate_start,
1728- remainder_start,
1729- & mut * candidates,
1730- fake_borrows,
1731- ) ;
1732- candidate_start
1733- } else {
1734- * remainder_start. get_or_insert_with ( || this. cfg . start_new_block ( ) )
1735- }
1736- } )
1737- . collect ( ) ;
1738-
1739- if !candidates. is_empty ( ) {
1740- let remainder_start = remainder_start. unwrap_or_else ( || this. cfg . start_new_block ( ) ) ;
1741- this. match_candidates (
1742- span,
1743- scrutinee_span,
1744- remainder_start,
1745- otherwise_block,
1746- candidates,
1747- fake_borrows,
1748- ) ;
1749- } ;
1750-
1751- target_blocks
1729+ let step = MatchAutomatonStep {
1730+ span,
1731+ test,
1732+ place : match_place,
1733+ remaining_candidates : candidates,
1734+ target_candidates,
1735+ otherwise_block,
1736+ fake_borrows,
17521737 } ;
1753-
1754- self . perform_test ( span, scrutinee_span, block, & match_place, & test, make_target_blocks) ;
1738+ self . perform_test ( span, scrutinee_span, block, step) ;
17551739 }
17561740
17571741 /// Determine the fake borrows that are needed from a set of places that
0 commit comments