@@ -173,17 +173,22 @@ impl Visitor<'tcx> for GatherAssignedLocalsVisitor<'_, '_, 'tcx> {
173
173
) {
174
174
let local = find_local_in_place ( place) ;
175
175
176
- // Conservatively check a subset of `Rvalue`s we know our
177
- // benchmarks track, for example `html5ever`.
176
+ // Find those cases where there is a `Place` consumed by
177
+ // `rvalue` and we know that all regions in its type will be
178
+ // incorporated into `place`, the `Place` we are assigning to.
178
179
match rvalue {
180
+ // `x = y` is the simplest possible case.
179
181
Rvalue :: Use ( op) => self . union_locals_if_needed ( local, find_local_in_operand ( op) ) ,
182
+
183
+ // `X = &'r P` -- the type of `X` will be `&'r T_P`, where
184
+ // `T_P` is the type of `P`.
180
185
Rvalue :: Ref ( _, _, place) => {
181
186
// Special case: if you have `X = &*Y` (or `X = &**Y`
182
187
// etc), then the outlives relationships will ensure
183
188
// that all regions in `Y` are constrained by regions
184
189
// in `X` -- this is because the lifetimes of the
185
190
// references we deref through are required to outlive
186
- // the borrow lifetime (which appears in `X`).
191
+ // the borrow lifetime `'r` (which appears in `X`).
187
192
//
188
193
// (We don't actually need to check the type of `Y`:
189
194
// since `ProjectionElem::Deref` represents a built-in
@@ -204,16 +209,23 @@ impl Visitor<'tcx> for GatherAssignedLocalsVisitor<'_, '_, 'tcx> {
204
209
}
205
210
206
211
Rvalue :: Cast ( kind, op, _) => match kind {
207
- CastKind :: Unsize => self . union_locals_if_needed ( local, find_local_in_operand ( op) ) ,
212
+ CastKind :: Unsize => {
213
+ // Casting a `&[T; N]` to `&[T]` or `&Foo` to `&Trait` --
214
+ // in both cases, no regions are "lost".
215
+ self . union_locals_if_needed ( local, find_local_in_operand ( op) )
216
+ }
208
217
_ => ( ) ,
209
218
} ,
210
219
220
+ // Constructing an aggregate like `(x,)` or `Foo { x }`
221
+ // includes the full type of `x`.
211
222
Rvalue :: Aggregate ( _, ops) => {
212
223
for rvalue in ops. iter ( ) . map ( find_local_in_operand) {
213
224
self . union_locals_if_needed ( local, rvalue) ;
214
225
}
215
226
}
216
227
228
+ // For other things, be conservative and do not union.
217
229
_ => ( ) ,
218
230
} ;
219
231
0 commit comments