@@ -436,19 +436,15 @@ fn do_mir_borrowck<'tcx>(
436
436
// Compute and report region errors, if any.
437
437
mbcx. report_region_errors ( nll_errors) ;
438
438
439
- if body. basic_blocks . is_cfg_cyclic ( ) {
440
- let ( mut flow_analysis, flow_entry_states) =
441
- get_flow_results ( tcx, body, & move_data, & borrow_set, & regioncx) ;
442
- visit_results (
443
- body,
444
- traversal:: reverse_postorder ( body) . map ( |( bb, _) | bb) ,
445
- & mut flow_analysis,
446
- & flow_entry_states,
447
- & mut mbcx,
448
- ) ;
449
- } else {
450
- compute_dataflow ( tcx, body, & move_data, & borrow_set, & regioncx, & mut mbcx) ;
451
- }
439
+ let ( mut flow_analysis, flow_entry_states) =
440
+ get_flow_results ( tcx, body, & move_data, & borrow_set, & regioncx) ;
441
+ visit_results (
442
+ body,
443
+ traversal:: reverse_postorder ( body) . map ( |( bb, _) | bb) ,
444
+ & mut flow_analysis,
445
+ & flow_entry_states,
446
+ & mut mbcx,
447
+ ) ;
452
448
453
449
mbcx. report_move_errors ( ) ;
454
450
@@ -501,186 +497,6 @@ fn do_mir_borrowck<'tcx>(
501
497
result
502
498
}
503
499
504
- fn compute_dataflow < ' a , ' tcx > (
505
- tcx : TyCtxt < ' tcx > ,
506
- body : & ' a Body < ' tcx > ,
507
-
508
- move_data : & ' a MoveData < ' tcx > ,
509
- borrow_set : & ' a BorrowSet < ' tcx > ,
510
- regioncx : & RegionInferenceContext < ' tcx > ,
511
-
512
- vis : & mut MirBorrowckCtxt < ' a , ' _ , ' tcx > ,
513
- ) {
514
- let borrows = Borrows :: new ( tcx, body, regioncx, borrow_set) ;
515
- let uninits = MaybeUninitializedPlaces :: new ( tcx, body, move_data) ;
516
- let ever_inits = EverInitializedPlaces :: new ( body, move_data) ;
517
-
518
- let mut analysis = Borrowck { borrows, uninits, ever_inits } ;
519
-
520
- // Set up lazy state for the CFG
521
- use rustc_middle:: mir;
522
- use rustc_mir_dataflow:: JoinSemiLattice ;
523
-
524
- let mut results: IndexVec < BasicBlock , Option < BorrowckDomain > > =
525
- IndexVec :: from_elem_n ( None , body. basic_blocks . len ( ) ) ;
526
-
527
- // Ensure the start block has some state in it;
528
- results[ mir:: START_BLOCK ] = Some ( analysis. bottom_value ( body) ) ;
529
- analysis. initialize_start_block ( body, results[ mir:: START_BLOCK ] . as_mut ( ) . unwrap ( ) ) ;
530
-
531
- for ( _idx, ( block, block_data) ) in traversal:: reverse_postorder ( body) . enumerate ( ) {
532
- // Apply effects in block
533
- let mut block_state = results[ block] . take ( ) . unwrap_or_else ( || analysis. bottom_value ( body) ) ;
534
-
535
- vis. visit_block_start ( & mut block_state) ;
536
-
537
- for ( statement_index, statement) in block_data. statements . iter ( ) . enumerate ( ) {
538
- let location = Location { block, statement_index } ;
539
- analysis. apply_early_statement_effect ( & mut block_state, statement, location) ;
540
- vis. visit_after_early_statement_effect (
541
- & mut analysis,
542
- & block_state,
543
- statement,
544
- location,
545
- ) ;
546
-
547
- analysis. apply_primary_statement_effect ( & mut block_state, statement, location) ;
548
- vis. visit_after_primary_statement_effect (
549
- & mut analysis,
550
- & block_state,
551
- statement,
552
- location,
553
- ) ;
554
- }
555
- let terminator = block_data. terminator ( ) ;
556
- let location = Location { block, statement_index : block_data. statements . len ( ) } ;
557
- analysis. apply_early_terminator_effect ( & mut block_state, terminator, location) ;
558
- vis. visit_after_early_terminator_effect ( & mut analysis, & block_state, terminator, location) ;
559
-
560
- let edges =
561
- analysis. apply_primary_terminator_effect ( & mut block_state, terminator, location) ;
562
- vis. visit_after_primary_terminator_effect (
563
- & mut analysis,
564
- & block_state,
565
- terminator,
566
- location,
567
- ) ;
568
-
569
- // notify visitor the block is ready
570
- vis. visit_block_end ( & mut block_state) ;
571
-
572
- match edges {
573
- TerminatorEdges :: None => { }
574
- TerminatorEdges :: Single ( target) => match results[ target] . as_mut ( ) {
575
- None => {
576
- results[ target] = Some ( block_state) ;
577
- }
578
- Some ( existing_state) => {
579
- existing_state. join ( & block_state) ;
580
- }
581
- } ,
582
- TerminatorEdges :: Double ( target, unwind) if target == unwind => {
583
- // wtf
584
- match results[ target] . as_mut ( ) {
585
- None => {
586
- results[ target] = Some ( block_state) ;
587
- }
588
- Some ( existing_state) => {
589
- existing_state. join ( & block_state) ;
590
- }
591
- }
592
- }
593
- TerminatorEdges :: Double ( target, unwind) => match results. pick2_mut ( target, unwind) {
594
- ( None , None ) => {
595
- results[ target] = Some ( block_state. clone ( ) ) ;
596
- results[ unwind] = Some ( block_state) ;
597
- }
598
- ( None , Some ( unwind_state) ) => {
599
- unwind_state. join ( & block_state) ;
600
- results[ target] = Some ( block_state) ;
601
- }
602
- ( Some ( target_state) , None ) => {
603
- target_state. join ( & block_state) ;
604
- results[ unwind] = Some ( block_state) ;
605
- }
606
- ( Some ( target_state) , Some ( unwind_state) ) => {
607
- target_state. join ( & block_state) ;
608
- unwind_state. join ( & block_state) ;
609
- }
610
- } ,
611
- TerminatorEdges :: AssignOnReturn { return_, cleanup, place } => {
612
- // This must be done *first*, otherwise the unwind path will see the assignments.
613
- if let Some ( cleanup) = cleanup {
614
- match results[ cleanup] . as_mut ( ) {
615
- None => {
616
- results[ cleanup] = Some ( block_state. clone ( ) ) ;
617
- }
618
- Some ( existing_state) => {
619
- existing_state. join ( & block_state) ;
620
- }
621
- }
622
- }
623
-
624
- if !return_. is_empty ( ) {
625
- analysis. apply_call_return_effect ( & mut block_state, block, place) ;
626
-
627
- // fixme: optimize, if we've merged the previous target states instead
628
- // of moving, we don't need to clone it.
629
-
630
- let target_count = return_. len ( ) ;
631
- for & target in return_. iter ( ) . take ( target_count - 1 ) {
632
- match results[ target] . as_mut ( ) {
633
- None => {
634
- results[ target] = Some ( block_state. clone ( ) ) ;
635
- }
636
- Some ( existing_state) => {
637
- existing_state. join ( & block_state) ;
638
- }
639
- }
640
- }
641
-
642
- let target = * return_. last ( ) . unwrap ( ) ;
643
- match results[ target] . as_mut ( ) {
644
- None => {
645
- results[ target] = Some ( block_state. clone ( ) ) ;
646
- }
647
- Some ( existing_state) => {
648
- existing_state. join ( & block_state) ;
649
- }
650
- }
651
- }
652
- }
653
- TerminatorEdges :: SwitchInt { targets, discr } => {
654
- if let Some ( _data) = analysis. get_switch_int_data ( block, discr) {
655
- todo ! ( "wat. this is unused in tests" ) ;
656
- } else {
657
- let target_count = targets. all_targets ( ) . len ( ) ;
658
- for & target in targets. all_targets ( ) . iter ( ) . take ( target_count - 1 ) {
659
- match results[ target] . as_mut ( ) {
660
- None => {
661
- results[ target] = Some ( block_state. clone ( ) ) ;
662
- }
663
- Some ( existing_state) => {
664
- existing_state. join ( & block_state) ;
665
- }
666
- }
667
- }
668
-
669
- let target = * targets. all_targets ( ) . last ( ) . unwrap ( ) ;
670
- match results[ target] . as_mut ( ) {
671
- None => {
672
- results[ target] = Some ( block_state. clone ( ) ) ;
673
- }
674
- Some ( existing_state) => {
675
- existing_state. join ( & block_state) ;
676
- }
677
- }
678
- }
679
- }
680
- }
681
- }
682
- }
683
-
684
500
fn get_flow_results < ' a , ' tcx > (
685
501
tcx : TyCtxt < ' tcx > ,
686
502
body : & ' a Body < ' tcx > ,
0 commit comments