You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* "Optimization: borrow the ref, not data owned by ref."
376
-
* If Place contains a deref of an `&`...
377
-
* ...or something
372
+
* Disjoint capture over immutable reference doesn't add too much value because the fields can either be borrowed immutably or copied.
373
+
* Edge case: Field that is accessed via the referece lives longer than the reference.
374
+
* Resolution: Only consider the last Deref
375
+
* If Place is (Base, Projections), where Projections is a list of size N.
376
+
* For all `i, 0 <= i < N`, Projections[i] != Deref
377
+
* Return (Place, Mode)
378
+
* If `l, 0 <= l < N` is the last/rightmost Deref Projection i.e. for any `i, l < i < N` Projection[i] != Deref,
379
+
and `Place.type_before_projection(l) = ty::Ref(.., Mutability::Not)`
380
+
* Let Place1 = (Base, Projections[0..=l])
381
+
* Return (Place1, Ref)
378
382
379
383
## Key examples
380
384
381
385
### box-mut
382
386
383
387
```rust
388
+
structFoo { x:i32 }
389
+
384
390
fnbox_mut() {
385
391
letmuts=Foo { x:0 } ;
386
392
387
393
letpx=&muts;
388
394
letbx=Box::new(px);
389
395
390
396
391
-
letc=#[rustc_capture_analysis] move||bx.x +=10;
397
+
letc=move||bx.x +=10;
392
398
// Mutable reference to this place:
393
399
// (*(*bx)).x
394
400
// ^ ^
@@ -397,7 +403,8 @@ fn box_mut() {
397
403
}
398
404
```
399
405
400
-
```
406
+
<!-- ignore: Omit error about unterminated string literal when representing c_prime -->
407
+
```ignore
401
408
Closure mode = move
402
409
C = {
403
410
(ref mut, (*(*bx)).x)
@@ -412,37 +419,57 @@ Output is the same: `C' = C`
412
419
When you have a closure that both references a packed field (which is unsafe) and moves from it (which is safe) we capture the entire struct, rather than just moving the field. This is to aid in predictability, so that removing the move doesn't make the closure become unsafe:
413
420
414
421
```rust
415
-
print(&packed.x);
416
-
move_value(packed.x);
422
+
#[repr(packed)]
423
+
structPacked { x:String }
424
+
425
+
# fnuse_ref<T>(_:&T) {}
426
+
# fnmove_value<T>(_:T) {}
427
+
428
+
fnmain() {
429
+
letpacked=Packed { x:String::new() };
430
+
431
+
letc=|| {
432
+
use_ref(&packed.x);
433
+
move_value(packed.x);
434
+
};
435
+
436
+
c();
437
+
}
438
+
```
439
+
440
+
<!-- ignore: Omit error about unterminated string literal when representing c_prime -->
0 commit comments