@@ -454,6 +454,110 @@ fn foo(a: &mut i32) {
454
454
```
455
455
"## ,
456
456
457
+ E0504 : r##"
458
+ This error occurs when an attempt is made to move a borrowed variable into a
459
+ closure.
460
+
461
+ Example of erroneous code:
462
+
463
+ ```compile_fail
464
+ struct FancyNum {
465
+ num: u8
466
+ }
467
+
468
+ fn main() {
469
+ let fancy_num = FancyNum { num: 5 };
470
+ let fancy_ref = &fancy_num;
471
+
472
+ let x = move || {
473
+ println!("child function: {}", fancy_num.num);
474
+ // error: cannot move `fancy_num` into closure because it is borrowed
475
+ };
476
+
477
+ x();
478
+ println!("main function: {}", fancy_ref.num);
479
+ }
480
+ ```
481
+
482
+ Here, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into
483
+ the closure `x`. There is no way to move a value into a closure while it is
484
+ borrowed, as that would invalidate the borrow.
485
+
486
+ If the closure can't outlive the value being moved, try using a reference
487
+ rather than moving:
488
+
489
+ ```
490
+ struct FancyNum {
491
+ num: u8
492
+ }
493
+
494
+ fn main() {
495
+ let fancy_num = FancyNum { num: 5 };
496
+ let fancy_ref = &fancy_num;
497
+
498
+ let x = move || {
499
+ // fancy_ref is usable here because it doesn't move `fancy_num`
500
+ println!("child function: {}", fancy_ref.num);
501
+ };
502
+
503
+ x();
504
+
505
+ println!("main function: {}", fancy_num.num);
506
+ }
507
+ ```
508
+
509
+ If the value has to be borrowed and then moved, try limiting the lifetime of
510
+ the borrow using a scoped block:
511
+
512
+ ```
513
+ struct FancyNum {
514
+ num: u8
515
+ }
516
+
517
+ fn main() {
518
+ let fancy_num = FancyNum { num: 5 };
519
+
520
+ {
521
+ let fancy_ref = &fancy_num;
522
+ println!("main function: {}", fancy_ref.num);
523
+ // `fancy_ref` goes out of scope here
524
+ }
525
+
526
+ let x = move || {
527
+ // `fancy_num` can be moved now (no more references exist)
528
+ println!("child function: {}", fancy_num.num);
529
+ };
530
+
531
+ x();
532
+ }
533
+ ```
534
+
535
+ If the lifetime of a reference isn't enough, such as in the case of threading,
536
+ consider using an `Arc` to create a reference-counted value:
537
+
538
+ ```
539
+ use std::sync::Arc;
540
+ use std::thread;
541
+
542
+ struct FancyNum {
543
+ num: u8
544
+ }
545
+
546
+ fn main() {
547
+ let fancy_ref1 = Arc::new(FancyNum { num: 5 });
548
+ let fancy_ref2 = fancy_ref1.clone();
549
+
550
+ let x = thread::spawn(move || {
551
+ // `fancy_ref1` can be moved and has a `'static` lifetime
552
+ println!("child thread: {}", fancy_ref1.num);
553
+ });
554
+
555
+ x.join().expect("child thread should finish");
556
+ println!("main thread: {}", fancy_ref2.num);
557
+ }
558
+ ```
559
+ "## ,
560
+
457
561
E0506 : r##"
458
562
This error occurs when an attempt is made to assign to a borrowed value.
459
563
@@ -756,7 +860,6 @@ register_diagnostics! {
756
860
E0500 , // closure requires unique access to `..` but .. is already borrowed
757
861
E0502 , // cannot borrow `..`.. as .. because .. is also borrowed as ...
758
862
E0503 , // cannot use `..` because it was mutably borrowed
759
- E0504 , // cannot move `..` into closure because it is borrowed
760
863
E0505 , // cannot move out of `..` because it is borrowed
761
864
E0508 , // cannot move out of type `..`, a non-copy fixed-size array
762
865
E0524 , // two closures require unique access to `..` at the same time
0 commit comments