@@ -92,6 +92,7 @@ impl<'tcx> Stack {
92
92
}
93
93
}
94
94
95
+ // Check that all Unique items fall within unique_range.
95
96
for ( idx, item) in self . borrows . iter ( ) . enumerate ( ) {
96
97
if item. perm ( ) == Permission :: Unique {
97
98
assert ! (
@@ -102,6 +103,18 @@ impl<'tcx> Stack {
102
103
) ;
103
104
}
104
105
}
106
+
107
+ // Check that the unique_range is a valid index into the borrow stack.
108
+ let uniques = & self . borrows [ self . unique_range . clone ( ) ] ;
109
+
110
+ // Check that the start of the unique_range is precise.
111
+ if let Some ( first_unique) = uniques. first ( ) {
112
+ assert_eq ! ( first_unique. perm( ) , Permission :: Unique ) ;
113
+ }
114
+ // We cannot assert that the unique range is exact on the upper end.
115
+ // When we pop items within the unique range, setting the end of the range precisely
116
+ // require doing a linear search of the borrow stack, which is exactly the kind of
117
+ // operation that all this caching exists to avoid.
105
118
}
106
119
107
120
/// Find the item granting the given kind of access to the given tag, and return where
@@ -227,9 +240,14 @@ impl<'tcx> Stack {
227
240
self . unique_range . end += 1 ;
228
241
}
229
242
if new. perm ( ) == Permission :: Unique {
230
- // Make sure the possibly-unique range contains the new borrow
231
- self . unique_range . start = self . unique_range . start . min ( new_idx) ;
232
- self . unique_range . end = self . unique_range . end . max ( new_idx + 1 ) ;
243
+ // If this is the first Unique, set the range to contain just the new item.
244
+ if self . unique_range == ( 0 ..0 ) {
245
+ self . unique_range = new_idx..new_idx + 1 ;
246
+ } else {
247
+ // We already have other Unique items, expand the range to include the new item
248
+ self . unique_range . start = self . unique_range . start . min ( new_idx) ;
249
+ self . unique_range . end = self . unique_range . end . max ( new_idx + 1 ) ;
250
+ }
233
251
}
234
252
235
253
// The above insert changes the meaning of every index in the cache >= new_idx, so now
@@ -282,6 +300,10 @@ impl<'tcx> Stack {
282
300
// cache when it has been cleared and not yet refilled.
283
301
self . borrows . clear ( ) ;
284
302
self . unknown_bottom = Some ( tag) ;
303
+ #[ cfg( feature = "stack-cache" ) ]
304
+ {
305
+ self . unique_range = 0 ..0 ;
306
+ }
285
307
}
286
308
287
309
/// Find all `Unique` elements in this borrow stack above `granting_idx`, pass a copy of them
@@ -298,7 +320,7 @@ impl<'tcx> Stack {
298
320
299
321
if disable_start <= unique_range. end {
300
322
let lower = unique_range. start . max ( disable_start) ;
301
- let upper = ( unique_range . end + 1 ) . min ( self . borrows . len ( ) ) ;
323
+ let upper = self . unique_range . end ;
302
324
for item in & mut self . borrows [ lower..upper] {
303
325
if item. perm ( ) == Permission :: Unique {
304
326
log:: trace!( "access: disabling item {:?}" , item) ;
@@ -315,14 +337,14 @@ impl<'tcx> Stack {
315
337
}
316
338
317
339
#[ cfg( feature = "stack-cache" ) ]
318
- if disable_start < self . unique_range . start {
340
+ if disable_start <= self . unique_range . start {
319
341
// We disabled all Unique items
320
342
self . unique_range . start = 0 ;
321
343
self . unique_range . end = 0 ;
322
344
} else {
323
- // Truncate the range to disable_start. This is + 2 because we are only removing
324
- // elements after disable_start, and this range does not include the end .
325
- self . unique_range . end = self . unique_range . end . min ( disable_start + 1 ) ;
345
+ // Truncate the range to only include items up to the index that we started disabling
346
+ // at .
347
+ self . unique_range . end = self . unique_range . end . min ( disable_start) ;
326
348
}
327
349
328
350
#[ cfg( debug_assertions) ]
@@ -369,12 +391,12 @@ impl<'tcx> Stack {
369
391
self . cache . items [ i] = base_tag;
370
392
}
371
393
372
- if start < self . unique_range . start . saturating_sub ( 1 ) {
394
+ if start <= self . unique_range . start {
373
395
// We removed all the Unique items
374
396
self . unique_range = 0 ..0 ;
375
397
} else {
376
398
// Ensure the range doesn't extend past the new top of the stack
377
- self . unique_range . end = self . unique_range . end . min ( start + 1 ) ;
399
+ self . unique_range . end = self . unique_range . end . min ( start) ;
378
400
}
379
401
} else {
380
402
self . unique_range = 0 ..0 ;
0 commit comments