5
5
//! This also includes code for pattern bindings in `let` statements and
6
6
//! function parameters.
7
7
8
+ use crate :: build:: expr:: as_place:: PlaceBuilder ;
9
+ use crate :: build:: scope:: DropKind ;
10
+ use crate :: build:: ForGuard :: { self , OutsideGuard , RefWithinGuard } ;
11
+ use crate :: build:: {
12
+ coverageinfo, BlockAnd , BlockAndExtension , Builder , GuardFrame , GuardFrameLocal , LocalsForNode ,
13
+ } ;
14
+
8
15
use rustc_data_structures:: fx:: FxIndexMap ;
9
16
use rustc_data_structures:: stack:: ensure_sufficient_stack;
10
17
use rustc_hir:: { BindingMode , ByRef } ;
@@ -18,12 +25,6 @@ use rustc_span::{BytePos, Pos, Span};
18
25
use rustc_target:: abi:: VariantIdx ;
19
26
use tracing:: { debug, instrument} ;
20
27
21
- use crate :: build:: ForGuard :: { self , OutsideGuard , RefWithinGuard } ;
22
- use crate :: build:: expr:: as_place:: PlaceBuilder ;
23
- use crate :: build:: scope:: DropKind ;
24
- use crate :: build:: {
25
- BlockAnd , BlockAndExtension , Builder , GuardFrame , GuardFrameLocal , LocalsForNode , coverageinfo,
26
- } ;
27
28
28
29
// helper functions, broken out by category:
29
30
mod match_pair;
@@ -453,8 +454,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
453
454
opt_scrutinee_place,
454
455
) ;
455
456
456
- // FIXME: Propagate this info down to codegen
457
- let pre_binding_block = branch. sub_branches [ 0 ] . otherwise_block ;
457
+ let sub_branches: Vec < _ > = branch
458
+ . sub_branches
459
+ . iter ( )
460
+ . map ( |b| coverageinfo:: MatchArmSubBranch {
461
+ source_info : this. source_info ( b. span ) ,
462
+ start_block : b. start_block ,
463
+ } )
464
+ . collect ( ) ;
458
465
459
466
let arm_block = this. bind_pattern (
460
467
outer_source_info,
@@ -468,7 +475,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
468
475
if let Some ( coverage_match_arms) = coverage_match_arms. as_mut ( ) {
469
476
coverage_match_arms. push ( coverageinfo:: MatchArm {
470
477
source_info : this. source_info ( arm. pattern . span ) ,
471
- pre_binding_block : Some ( pre_binding_block ) ,
478
+ sub_branches ,
472
479
arm_block,
473
480
} )
474
481
}
@@ -1391,6 +1398,8 @@ pub(crate) struct ArmHasGuard(pub(crate) bool);
1391
1398
#[ derive( Debug ) ]
1392
1399
struct MatchTreeSubBranch < ' tcx > {
1393
1400
span : Span ,
1401
+ /// The first block in this sub branch.
1402
+ start_block : Option < BasicBlock > ,
1394
1403
/// The block that is branched to if the corresponding subpattern matches.
1395
1404
success_block : BasicBlock ,
1396
1405
/// The block to branch to if this arm had a guard and the guard fails.
@@ -1441,6 +1450,7 @@ impl<'tcx> MatchTreeSubBranch<'tcx> {
1441
1450
debug_assert ! ( candidate. match_pairs. is_empty( ) ) ;
1442
1451
MatchTreeSubBranch {
1443
1452
span : candidate. extra_data . span ,
1453
+ start_block : candidate. false_edge_start_block ,
1444
1454
success_block : candidate. pre_binding_block . unwrap ( ) ,
1445
1455
otherwise_block : candidate. otherwise_block . unwrap ( ) ,
1446
1456
bindings : parent_data
@@ -1860,7 +1870,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1860
1870
} ) ;
1861
1871
for candidate in candidates_to_expand. iter_mut ( ) {
1862
1872
if !candidate. subcandidates . is_empty ( ) {
1863
- self . merge_trivial_subcandidates ( candidate) ;
1873
+ // FIXME: Support merging trival candidates in branch coverage instrumentation
1874
+ if self . coverage_info . is_none ( ) {
1875
+ self . merge_trivial_subcandidates ( candidate) ;
1876
+ }
1864
1877
self . remove_never_subcandidates ( candidate) ;
1865
1878
}
1866
1879
}
0 commit comments