@@ -386,6 +386,109 @@ fn foo(a: &mut i32) {
386
386
let bar = || {
387
387
inside_closure(a)
388
388
};
389
+ ```
390
+ "## ,
391
+
392
+ E0504 : r##"
393
+ This error occurs when an attempt is made to move a borrowed variable into a
394
+ closure.
395
+
396
+ Example of erroneous code:
397
+
398
+ ```compile_fail
399
+ struct FancyNum {
400
+ num: u8
401
+ }
402
+
403
+ fn main() {
404
+ let fancy_num = FancyNum { num: 5 };
405
+ let fancy_ref = &fancy_num;
406
+
407
+ let x = move || {
408
+ println!("child function: {}", fancy_num.num);
409
+ // error: cannot move `fancy_num` into closure because it is borrowed
410
+ };
411
+
412
+ x();
413
+ println!("main function: {}", fancy_ref.num);
414
+ }
415
+ ```
416
+
417
+ Here, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into
418
+ the closure `x`. There is no way to move a value into a closure while it is
419
+ borrowed, as that would invalidate the borrow.
420
+
421
+ If the closure can't outlive the value being moved, try using a reference
422
+ rather than moving:
423
+
424
+ ```
425
+ struct FancyNum {
426
+ num: u8
427
+ }
428
+
429
+ fn main() {
430
+ let fancy_num = FancyNum { num: 5 };
431
+ let fancy_ref = &fancy_num;
432
+
433
+ let x = move || {
434
+ // fancy_ref is usable here because it doesn't move `fancy_num`
435
+ println!("child function: {}", fancy_ref.num);
436
+ };
437
+
438
+ x();
439
+
440
+ println!("main function: {}", fancy_num.num);
441
+ }
442
+ ```
443
+
444
+ If the value has to be borrowed and then moved, try limiting the lifetime of
445
+ the borrow using a scoped block:
446
+
447
+ ```
448
+ struct FancyNum {
449
+ num: u8
450
+ }
451
+
452
+ fn main() {
453
+ let fancy_num = FancyNum { num: 5 };
454
+
455
+ {
456
+ let fancy_ref = &fancy_num;
457
+ println!("main function: {}", fancy_ref.num);
458
+ // `fancy_ref` goes out of scope here
459
+ }
460
+
461
+ let x = move || {
462
+ // `fancy_num` can be moved now (no more references exist)
463
+ println!("child function: {}", fancy_num.num);
464
+ };
465
+
466
+ x();
467
+ }
468
+ ```
469
+
470
+ If the lifetime of a reference isn't enough, such as in the case of threading,
471
+ consider using an `Arc` to create a reference-counted value:
472
+
473
+ ```
474
+ use std::sync::Arc;
475
+ use std::thread;
476
+
477
+ struct FancyNum {
478
+ num: u8
479
+ }
480
+
481
+ fn main() {
482
+ let fancy_ref1 = Arc::new(FancyNum { num: 5 });
483
+ let fancy_ref2 = fancy_ref1.clone();
484
+
485
+ let x = thread::spawn(move || {
486
+ // `fancy_ref1` can be moved and has a `'static` lifetime
487
+ println!("child thread: {}", fancy_ref1.num);
488
+ });
489
+
490
+ x.join().expect("child thread should finish");
491
+ println!("main thread: {}", fancy_ref2.num);
389
492
}
390
493
```
391
494
"## ,
@@ -514,7 +617,6 @@ register_diagnostics! {
514
617
E0500 , // closure requires unique access to `..` but .. is already borrowed
515
618
E0502 , // cannot borrow `..`.. as .. because .. is also borrowed as ...
516
619
E0503 , // cannot use `..` because it was mutably borrowed
517
- E0504 , // cannot move `..` into closure because it is borrowed
518
620
E0505 , // cannot move out of `..` because it is borrowed
519
621
E0506 , // cannot assign to `..` because it is borrowed
520
622
E0508 , // cannot move out of type `..`, a non-copy fixed-size array
0 commit comments