@@ -195,18 +195,18 @@ fn compute_replacement<'tcx>(
195
195
// including DEF. This violates the DEF dominates USE condition, and so is impossible.
196
196
let is_constant_place = |place : Place < ' _ > | {
197
197
// We only allow `Deref` as the first projection, to avoid surprises.
198
- if place . projection . first ( ) == Some ( & PlaceElem :: Deref ) {
198
+ if let Some ( ( & PlaceElem :: Deref , rest ) ) = place . projection . split_first ( ) {
199
199
// `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
200
200
// We approximate constness using SSAness.
201
- ssa. is_ssa ( place. local ) && place . projection [ 1 .. ] . iter ( ) . all ( PlaceElem :: is_stable_offset)
201
+ ssa. is_ssa ( place. local ) && rest . iter ( ) . all ( PlaceElem :: is_stable_offset)
202
202
} else {
203
203
storage_live. has_single_storage ( place. local )
204
204
&& place. projection [ ..] . iter ( ) . all ( PlaceElem :: is_stable_offset)
205
205
}
206
206
} ;
207
207
208
208
let mut can_perform_opt = |target : Place < ' tcx > , loc : Location | {
209
- if target. projection . first ( ) == Some ( & PlaceElem :: Deref ) {
209
+ if target. is_indirect_first_projection ( ) {
210
210
// We are creating a reborrow. As `place.local` is a reference, removing the storage
211
211
// statements should not make it much harder for LLVM to optimize.
212
212
storage_to_remove. insert ( target. local ) ;
@@ -266,15 +266,15 @@ fn compute_replacement<'tcx>(
266
266
Rvalue :: Ref ( _, _, place) | Rvalue :: RawPtr ( _, place) => {
267
267
let mut place = * place;
268
268
// Try to see through `place` in order to collapse reborrow chains.
269
- if place . projection . first ( ) == Some ( & PlaceElem :: Deref )
269
+ if let Some ( ( & PlaceElem :: Deref , rest ) ) = place . projection . split_first ( )
270
270
&& let Value :: Pointer ( target, inner_needs_unique) = targets[ place. local ]
271
271
// Only see through immutable reference and pointers, as we do not know yet if
272
272
// mutable references are fully replaced.
273
273
&& !inner_needs_unique
274
274
// Only collapse chain if the pointee is definitely live.
275
275
&& can_perform_opt ( target, location)
276
276
{
277
- place = target. project_deeper ( & place . projection [ 1 .. ] , tcx) ;
277
+ place = target. project_deeper ( rest , tcx) ;
278
278
}
279
279
assert_ne ! ( place. local, local) ;
280
280
if is_constant_place ( place) {
@@ -323,7 +323,7 @@ fn compute_replacement<'tcx>(
323
323
return ;
324
324
}
325
325
326
- if place. projection . first ( ) != Some ( & PlaceElem :: Deref ) {
326
+ if ! place. is_indirect_first_projection ( ) {
327
327
// This is not a dereference, nothing to do.
328
328
return ;
329
329
}
@@ -392,20 +392,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
392
392
}
393
393
394
394
fn visit_var_debug_info ( & mut self , debuginfo : & mut VarDebugInfo < ' tcx > ) {
395
- // If the debuginfo is a pointer to another place:
396
- // - if it's a reborrow, see through it;
397
- // - if it's a direct borrow, increase `debuginfo.references`.
395
+ // If the debuginfo is a pointer to another place
396
+ // and it's a reborrow: see through it
398
397
while let VarDebugInfoContents :: Place ( ref mut place) = debuginfo. value
399
398
&& place. projection . is_empty ( )
400
399
&& let Value :: Pointer ( target, _) = self . targets [ place. local ]
401
- && target. projection . iter ( ) . all ( |p| p . can_use_in_debuginfo ( ) )
400
+ && let & [ PlaceElem :: Deref ] = & target. projection [ .. ]
402
401
{
403
- if let Some ( ( & PlaceElem :: Deref , rest) ) = target. projection . split_last ( ) {
404
- * place = Place :: from ( target. local ) . project_deeper ( rest, self . tcx ) ;
405
- self . any_replacement = true ;
406
- } else {
407
- break ;
408
- }
402
+ * place = Place :: from ( target. local ) ;
403
+ self . any_replacement = true ;
409
404
}
410
405
411
406
// Simplify eventual projections left inside `debuginfo`.
@@ -414,9 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
414
409
415
410
fn visit_place ( & mut self , place : & mut Place < ' tcx > , ctxt : PlaceContext , loc : Location ) {
416
411
loop {
417
- if place. projection . first ( ) != Some ( & PlaceElem :: Deref ) {
418
- return ;
419
- }
412
+ let Some ( ( & PlaceElem :: Deref , rest) ) = place. projection . split_first ( ) else { return } ;
420
413
421
414
let Value :: Pointer ( target, _) = self . targets [ place. local ] else { return } ;
422
415
@@ -432,7 +425,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
432
425
return ;
433
426
}
434
427
435
- * place = target. project_deeper ( & place . projection [ 1 .. ] , self . tcx ) ;
428
+ * place = target. project_deeper ( rest , self . tcx ) ;
436
429
self . any_replacement = true ;
437
430
}
438
431
}
0 commit comments