@@ -450,8 +450,10 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
450
450
451
451
// Perform the DFS.
452
452
// `stack` is the stack of locations still under consideration
453
+ // `visited` is the set of points we have already visited
453
454
// `found_use` is an Option that becomes Some when we find a use
454
455
let mut stack = vec ! [ start_location] ;
456
+ let mut visited = FxHashSet ( ) ;
455
457
let mut found_use = None ;
456
458
while let Some ( curr_loc) = stack. pop ( ) {
457
459
let block_data = & self . mir . basic_blocks ( )
@@ -467,6 +469,11 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
467
469
continue ;
468
470
}
469
471
472
+ if !visited. insert ( curr_loc) {
473
+ debug ! ( " Already visited {:?}" , curr_loc) ;
474
+ continue ;
475
+ }
476
+
470
477
if self . location_contains_use ( curr_loc, assigned_place) {
471
478
// TODO: Handle this case a little more gracefully. Perhaps collect
472
479
// all uses in a vector, and find the point in the CFG that dominates
@@ -529,19 +536,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
529
536
fn kill_loans_out_of_scope_at_location ( & self ,
530
537
sets : & mut BlockSets < ReserveOrActivateIndex > ,
531
538
location : Location ) {
532
- /*
533
- XXX: bob_twinkles reintroduce this
534
- let block_data = &self.mir[location.block];
535
- if location.statement_index != block_data.statements.len() {
536
- let statement = &block_data.statements[location.statement_index];
537
- if let mir::StatementKind::EndRegion(region_scope) = statement.kind {
538
- for &borrow_index in &self.region_map[&ReScope(region_scope)] {
539
- sets.kill(&ReserveOrActivateIndex::reserved(borrow_index));
540
- sets.kill(&ReserveOrActivateIndex::active(borrow_index));
541
- }
542
- }
543
- }
544
- */
545
539
if let Some ( ref regioncx) = self . nonlexical_regioncx {
546
540
// NOTE: The state associated with a given `location`
547
541
// reflects the dataflow on entry to the statement. If it
@@ -575,6 +569,20 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
575
569
. map ( |b| ReserveOrActivateIndex :: active ( * b) ) ) ;
576
570
}
577
571
}
572
+
573
+ /// Performs the activations for a given location
574
+ fn perform_activations_at_location ( & self ,
575
+ sets : & mut BlockSets < ReserveOrActivateIndex > ,
576
+ location : Location ) {
577
+ // Handle activations
578
+ match self . activation_map . get ( & location) {
579
+ Some ( & activated) => {
580
+ debug ! ( "activating borrow {:?}" , activated) ;
581
+ sets. gen ( & ReserveOrActivateIndex :: active ( activated) )
582
+ }
583
+ None => { }
584
+ }
585
+ }
578
586
}
579
587
580
588
impl < ' a , ' gcx , ' tcx > BitDenotation for Borrows < ' a , ' gcx , ' tcx > {
@@ -605,13 +613,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
605
613
panic ! ( "could not find statement at location {:?}" ) ;
606
614
} ) ;
607
615
608
- // Handle activations
609
- match self . activation_map . get ( & location) {
610
- Some ( & activated) => {
611
- sets. gen ( & ReserveOrActivateIndex :: active ( activated) )
612
- }
613
- None => { }
614
- }
616
+ self . perform_activations_at_location ( sets, location) ;
617
+ self . kill_loans_out_of_scope_at_location ( sets, location) ;
615
618
616
619
match stmt. kind {
617
620
// EndRegion kills any borrows (reservations and active borrows both)
@@ -643,15 +646,17 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
643
646
644
647
if let mir:: Rvalue :: Ref ( region, _, ref place) = * rhs {
645
648
if is_unsafe_place ( self . tcx , self . mir , place) { return ; }
649
+ let index = self . location_map . get ( & location) . unwrap_or_else ( || {
650
+ panic ! ( "could not find BorrowIndex for location {:?}" , location) ;
651
+ } ) ;
652
+
646
653
if let RegionKind :: ReEmpty = region {
647
- // If the borrowed value is dead, the region for it
648
- // can be empty. Don't track the borrow in that case.
654
+ // If the borrowed value dies before the borrow is used, the region for
655
+ // the borrow can be empty. Don't track the borrow in that case.
656
+ sets. kill ( & ReserveOrActivateIndex :: active ( * index) ) ;
649
657
return
650
658
}
651
659
652
- let index = self . location_map . get ( & location) . unwrap_or_else ( || {
653
- panic ! ( "could not find BorrowIndex for location {:?}" , location) ;
654
- } ) ;
655
660
assert ! ( self . region_map. get( region) . unwrap_or_else( || {
656
661
panic!( "could not find BorrowIndexs for region {:?}" , region) ;
657
662
} ) . contains( & index) ) ;
@@ -714,14 +719,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
714
719
} ) ;
715
720
716
721
let term = block. terminator ( ) ;
722
+ self . perform_activations_at_location ( sets, location) ;
723
+ self . kill_loans_out_of_scope_at_location ( sets, location) ;
717
724
718
- // Handle activations
719
- match self . activation_map . get ( & location) {
720
- Some ( & activated) => {
721
- sets. gen ( & ReserveOrActivateIndex :: active ( activated) )
722
- }
723
- None => { }
724
- }
725
725
726
726
match term. kind {
727
727
mir:: TerminatorKind :: Resume |
0 commit comments