@@ -195,18 +195,18 @@ fn compute_replacement<'tcx>(
195195 // including DEF. This violates the DEF dominates USE condition, and so is impossible.
196196 let is_constant_place = |place : Place < ' _ > | {
197197 // 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 ( ) {
199199 // `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
200200 // 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)
202202 } else {
203203 storage_live. has_single_storage ( place. local )
204204 && place. projection [ ..] . iter ( ) . all ( PlaceElem :: is_stable_offset)
205205 }
206206 } ;
207207
208208 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 ( ) {
210210 // We are creating a reborrow. As `place.local` is a reference, removing the storage
211211 // statements should not make it much harder for LLVM to optimize.
212212 storage_to_remove. insert ( target. local ) ;
@@ -266,15 +266,15 @@ fn compute_replacement<'tcx>(
266266 Rvalue :: Ref ( _, _, place) | Rvalue :: RawPtr ( _, place) => {
267267 let mut place = * place;
268268 // 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 ( )
270270 && let Value :: Pointer ( target, inner_needs_unique) = targets[ place. local ]
271271 // Only see through immutable reference and pointers, as we do not know yet if
272272 // mutable references are fully replaced.
273273 && !inner_needs_unique
274274 // Only collapse chain if the pointee is definitely live.
275275 && can_perform_opt ( target, location)
276276 {
277- place = target. project_deeper ( & place . projection [ 1 .. ] , tcx) ;
277+ place = target. project_deeper ( rest , tcx) ;
278278 }
279279 assert_ne ! ( place. local, local) ;
280280 if is_constant_place ( place) {
@@ -323,7 +323,7 @@ fn compute_replacement<'tcx>(
323323 return ;
324324 }
325325
326- if place. projection . first ( ) != Some ( & PlaceElem :: Deref ) {
326+ if ! place. is_indirect_first_projection ( ) {
327327 // This is not a dereference, nothing to do.
328328 return ;
329329 }
@@ -392,20 +392,15 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
392392 }
393393
394394 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
398397 while let VarDebugInfoContents :: Place ( ref mut place) = debuginfo. value
399398 && place. projection . is_empty ( )
400399 && 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 [ .. ]
402401 {
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 ;
409404 }
410405
411406 // Simplify eventual projections left inside `debuginfo`.
@@ -414,9 +409,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
414409
415410 fn visit_place ( & mut self , place : & mut Place < ' tcx > , ctxt : PlaceContext , loc : Location ) {
416411 loop {
417- if place. projection . first ( ) != Some ( & PlaceElem :: Deref ) {
418- return ;
419- }
412+ let Some ( ( & PlaceElem :: Deref , rest) ) = place. projection . split_first ( ) else { return } ;
420413
421414 let Value :: Pointer ( target, _) = self . targets [ place. local ] else { return } ;
422415
@@ -432,7 +425,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
432425 return ;
433426 }
434427
435- * place = target. project_deeper ( & place . projection [ 1 .. ] , self . tcx ) ;
428+ * place = target. project_deeper ( rest , self . tcx ) ;
436429 self . any_replacement = true ;
437430 }
438431 }
0 commit comments