@@ -59,9 +59,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
59
59
borrows_out_of_scope_at_location : & mut FxHashMap < Location , Vec < BorrowIndex > > ,
60
60
borrow_index : BorrowIndex ,
61
61
borrow_region : RegionVid ,
62
- location : Location
62
+ location : Location ,
63
+ visited_locations : & mut Vec < Location >
63
64
) {
64
- // Start by dealing with the current location.
65
+ // Check if we have already visited this location and skip
66
+ // it if we have - avoids infinite loops.
67
+ if visited_locations. contains ( & location) { return ; }
68
+ visited_locations. push ( location. clone ( ) ) ;
69
+
70
+ // Next, add the borrow index to the current location's vector if the region does
71
+ // not contain the point at that location (or create a new vector if required).
65
72
if !regioncx. region_contains_point ( borrow_region, location) {
66
73
borrows_out_of_scope_at_location
67
74
. entry ( location. clone ( ) )
@@ -80,57 +87,65 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
80
87
TerminatorKind :: FalseUnwind { real_target : target, .. } => {
81
88
precompute_borrows_out_of_scope (
82
89
mir, regioncx, borrows_out_of_scope_at_location,
83
- borrow_index, borrow_region, target. start_location ( )
90
+ borrow_index, borrow_region, target. start_location ( ) ,
91
+ visited_locations
84
92
) ;
85
93
} ,
86
94
TerminatorKind :: SwitchInt { ref targets, .. } => {
87
95
for block in targets {
88
96
precompute_borrows_out_of_scope (
89
97
mir, regioncx, borrows_out_of_scope_at_location,
90
- borrow_index, borrow_region, block. start_location ( )
98
+ borrow_index, borrow_region, block. start_location ( ) ,
99
+ visited_locations
91
100
) ;
92
101
}
93
102
} ,
94
103
TerminatorKind :: Drop { target, unwind, .. } |
95
104
TerminatorKind :: DropAndReplace { target, unwind, .. } => {
96
105
precompute_borrows_out_of_scope (
97
106
mir, regioncx, borrows_out_of_scope_at_location,
98
- borrow_index, borrow_region, target. start_location ( )
107
+ borrow_index, borrow_region, target. start_location ( ) ,
108
+ visited_locations
99
109
) ;
100
110
101
111
if let Some ( unwind_block) = unwind {
102
112
precompute_borrows_out_of_scope (
103
113
mir, regioncx, borrows_out_of_scope_at_location,
104
- borrow_index, borrow_region, unwind_block. start_location ( )
114
+ borrow_index, borrow_region, unwind_block. start_location ( ) ,
115
+ visited_locations
105
116
) ;
106
117
}
107
118
} ,
108
119
TerminatorKind :: Call { ref destination, cleanup, .. } => {
109
120
if let Some ( ( _, block) ) = destination {
110
121
precompute_borrows_out_of_scope (
111
122
mir, regioncx, borrows_out_of_scope_at_location,
112
- borrow_index, borrow_region, block. start_location ( )
123
+ borrow_index, borrow_region, block. start_location ( ) ,
124
+ visited_locations
113
125
) ;
114
126
}
115
127
116
128
if let Some ( block) = cleanup {
117
129
precompute_borrows_out_of_scope (
118
130
mir, regioncx, borrows_out_of_scope_at_location,
119
- borrow_index, borrow_region, block. start_location ( )
131
+ borrow_index, borrow_region, block. start_location ( ) ,
132
+ visited_locations
120
133
) ;
121
134
}
122
135
} ,
123
136
TerminatorKind :: Assert { target, cleanup, .. } |
124
137
TerminatorKind :: Yield { resume : target, drop : cleanup, .. } => {
125
138
precompute_borrows_out_of_scope (
126
139
mir, regioncx, borrows_out_of_scope_at_location,
127
- borrow_index, borrow_region, target. start_location ( )
140
+ borrow_index, borrow_region, target. start_location ( ) ,
141
+ visited_locations
128
142
) ;
129
143
130
144
if let Some ( block) = cleanup {
131
145
precompute_borrows_out_of_scope (
132
146
mir, regioncx, borrows_out_of_scope_at_location,
133
- borrow_index, borrow_region, block. start_location ( )
147
+ borrow_index, borrow_region, block. start_location ( ) ,
148
+ visited_locations
134
149
) ;
135
150
}
136
151
} ,
@@ -142,7 +157,7 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
142
157
} else {
143
158
precompute_borrows_out_of_scope ( mir, regioncx, borrows_out_of_scope_at_location,
144
159
borrow_index, borrow_region,
145
- location. successor_within_block ( ) ) ;
160
+ location. successor_within_block ( ) , visited_locations ) ;
146
161
}
147
162
}
148
163
@@ -167,7 +182,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
167
182
168
183
precompute_borrows_out_of_scope ( mir, & nonlexical_regioncx,
169
184
& mut borrows_out_of_scope_at_location,
170
- borrow_index, borrow_region, location) ;
185
+ borrow_index, borrow_region, location,
186
+ & mut Vec :: new ( ) ) ;
171
187
}
172
188
173
189
Borrows {
0 commit comments