@@ -251,15 +251,25 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
251251 }
252252 }
253253
254- /// Represent the *value* which would be read from `place`.
254+ /// Represent the *value* which would be read from `place`, and point `place` to a preexisting
255+ /// place with the same value (if that already exists).
255256 #[ instrument( level = "trace" , skip( self ) , ret) ]
256- fn simplify_place ( & mut self , place : & mut Place < ' tcx > , location : Location ) -> Option < VnIndex > {
257- // Another place that holds the same value.
257+ fn simplify_place_value (
258+ & mut self ,
259+ place : & mut Place < ' tcx > ,
260+ location : Location ,
261+ ) -> Option < VnIndex > {
262+ // Invariant: `place` and `place_ref` point to the same value, even if they point to
263+ // different memory locations.
258264 let mut place_ref = place. as_ref ( ) ;
259- let mut value = self . locals [ place. local ] ?;
260265
266+ // Invariant: `value` holds the value up-to the `index`th projection excluded.
267+ let mut value = self . locals [ place. local ] ?;
261268 for ( index, proj) in place. projection . iter ( ) . enumerate ( ) {
262269 if let Some ( local) = self . try_as_local ( value, location) {
270+ // Both `local` and `Place { local: place.local, projection: projection[..index] }`
271+ // hold the same value. Therefore, following place holds the value in the original
272+ // `place`.
263273 place_ref = PlaceRef { local, projection : & place. projection [ index..] } ;
264274 }
265275
@@ -301,14 +311,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
301311 }
302312
303313 if let Some ( local) = self . try_as_local ( value, location)
304- && local != place. local
314+ && local != place. local // in case we had no projection to begin with.
305315 {
306316 * place = local. into ( ) ;
307317 self . reused_locals . insert ( local) ;
308318 self . any_replacement = true ;
309319 } else if place_ref. local != place. local
310320 || place_ref. projection . len ( ) < place. projection . len ( )
311321 {
322+ // By the invariant on `place_ref`.
312323 * place = place_ref. project_deeper ( & [ ] , self . tcx ) ;
313324 self . reused_locals . insert ( place_ref. local ) ;
314325 self . any_replacement = true ;
@@ -326,7 +337,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
326337 match * operand {
327338 Operand :: Constant ( ref constant) => Some ( self . insert ( Value :: Constant ( constant. const_ ) ) ) ,
328339 Operand :: Copy ( ref mut place) | Operand :: Move ( ref mut place) => {
329- let value = self . simplify_place ( place, location) ?;
340+ let value = self . simplify_place_value ( place, location) ?;
330341 if let Some ( const_) = self . try_as_constant ( value) {
331342 * operand = Operand :: Constant ( Box :: new ( const_) ) ;
332343 self . any_replacement = true ;
@@ -379,7 +390,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
379390
380391 // Operations.
381392 Rvalue :: Len ( ref mut place) => {
382- let place = self . simplify_place ( place, location) ?;
393+ let place = self . simplify_place_value ( place, location) ?;
383394 Value :: Len ( place)
384395 }
385396 Rvalue :: Cast ( kind, ref mut value, to) => {
@@ -402,7 +413,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
402413 Value :: UnaryOp ( op, arg)
403414 }
404415 Rvalue :: Discriminant ( ref mut place) => {
405- let place = self . simplify_place ( place, location) ?;
416+ let place = self . simplify_place_value ( place, location) ?;
406417 Value :: Discriminant ( place)
407418 }
408419
0 commit comments