@@ -450,8 +450,10 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
450450
451451 // Perform the DFS.
452452 // `stack` is the stack of locations still under consideration
453+ // `visited` is the set of points we have already visited
453454 // `found_use` is an Option that becomes Some when we find a use
454455 let mut stack = vec ! [ start_location] ;
456+ let mut visited = FxHashSet ( ) ;
455457 let mut found_use = None ;
456458 while let Some ( curr_loc) = stack. pop ( ) {
457459 let block_data = & self . mir . basic_blocks ( )
@@ -467,6 +469,11 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
467469 continue ;
468470 }
469471
472+ if !visited. insert ( curr_loc) {
473+ debug ! ( " Already visited {:?}" , curr_loc) ;
474+ continue ;
475+ }
476+
470477 if self . location_contains_use ( curr_loc, assigned_place) {
471478 // TODO: Handle this case a little more gracefully. Perhaps collect
472479 // 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> {
529536 fn kill_loans_out_of_scope_at_location ( & self ,
530537 sets : & mut BlockSets < ReserveOrActivateIndex > ,
531538 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- */
545539 if let Some ( ref regioncx) = self . nonlexical_regioncx {
546540 // NOTE: The state associated with a given `location`
547541 // reflects the dataflow on entry to the statement. If it
@@ -575,6 +569,20 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
575569 . map ( |b| ReserveOrActivateIndex :: active ( * b) ) ) ;
576570 }
577571 }
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+ }
578586}
579587
580588impl < ' a , ' gcx , ' tcx > BitDenotation for Borrows < ' a , ' gcx , ' tcx > {
@@ -605,13 +613,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
605613 panic ! ( "could not find statement at location {:?}" ) ;
606614 } ) ;
607615
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) ;
615618
616619 match stmt. kind {
617620 // EndRegion kills any borrows (reservations and active borrows both)
@@ -643,15 +646,17 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
643646
644647 if let mir:: Rvalue :: Ref ( region, _, ref place) = * rhs {
645648 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+
646653 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) ) ;
649657 return
650658 }
651659
652- let index = self . location_map . get ( & location) . unwrap_or_else ( || {
653- panic ! ( "could not find BorrowIndex for location {:?}" , location) ;
654- } ) ;
655660 assert ! ( self . region_map. get( region) . unwrap_or_else( || {
656661 panic!( "could not find BorrowIndexs for region {:?}" , region) ;
657662 } ) . contains( & index) ) ;
@@ -714,14 +719,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
714719 } ) ;
715720
716721 let term = block. terminator ( ) ;
722+ self . perform_activations_at_location ( sets, location) ;
723+ self . kill_loans_out_of_scope_at_location ( sets, location) ;
717724
718- // Handle activations
719- match self . activation_map . get ( & location) {
720- Some ( & activated) => {
721- sets. gen ( & ReserveOrActivateIndex :: active ( activated) )
722- }
723- None => { }
724- }
725725
726726 match term. kind {
727727 mir:: TerminatorKind :: Resume |
0 commit comments