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."
390
-
* If Place contains a deref of an `&`...
391
-
* ...or something
386
+
* Disjoint capture over immutable reference doesn't add too much value because the fields can either be borrowed immutably or copied.
387
+
* Edge case: Field that is accessed via the referece lives longer than the reference.
388
+
* Resolution: Only consider the last Deref
389
+
* If Place is (Base, Projections), where Projections is a list of size N.
390
+
* For all `i, 0 <= i < N`, Projections[i] != Deref
391
+
* Return (Place, Mode)
392
+
* If `l, 0 <= l < N` is the last/rightmost Deref Projection i.e. for any `i, l < i < N` Projection[i] != Deref,
393
+
and `Place.type_before_projection(l) = ty::Ref(.., Mutability::Not)`
394
+
* Let Place1 = (Base, Projections[0..=l])
395
+
* Return (Place1, Ref)
392
396
393
397
## Key examples
394
398
395
399
### box-mut
396
400
397
401
```rust
402
+
structFoo { x:i32 }
403
+
398
404
fnbox_mut() {
399
405
letmuts=Foo { x:0 } ;
400
406
401
407
letpx=&muts;
402
408
letbx=Box::new(px);
403
409
404
410
405
-
letc=#[rustc_capture_analysis] move||bx.x +=10;
411
+
letc=move||bx.x +=10;
406
412
// Mutable reference to this place:
407
413
// (*(*bx)).x
408
414
// ^ ^
@@ -411,7 +417,8 @@ fn box_mut() {
411
417
}
412
418
```
413
419
414
-
```
420
+
<!-- ignore: Omit error about unterminated string literal when representing c_prime -->
421
+
```ignore
415
422
Closure mode = move
416
423
C = {
417
424
(ref mut, (*(*bx)).x)
@@ -426,37 +433,57 @@ Output is the same: `C' = C`
426
433
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:
427
434
428
435
```rust
429
-
print(&packed.x);
430
-
move_value(packed.x);
436
+
#[repr(packed)]
437
+
structPacked { x:String }
438
+
439
+
# fnuse_ref<T>(_:&T) {}
440
+
# fnmove_value<T>(_:T) {}
441
+
442
+
fnmain() {
443
+
letpacked=Packed { x:String::new() };
444
+
445
+
letc=|| {
446
+
use_ref(&packed.x);
447
+
move_value(packed.x);
448
+
};
449
+
450
+
c();
451
+
}
452
+
```
453
+
454
+
<!-- ignore: Omit error about unterminated string literal when representing c_prime -->
0 commit comments