@@ -454,6 +454,110 @@ fn foo(a: &mut i32) {
454454```
455455"## ,
456456
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+
457561E0506 : r##"
458562This error occurs when an attempt is made to assign to a borrowed value.
459563
@@ -756,7 +860,6 @@ register_diagnostics! {
756860 E0500 , // closure requires unique access to `..` but .. is already borrowed
757861 E0502 , // cannot borrow `..`.. as .. because .. is also borrowed as ...
758862 E0503 , // cannot use `..` because it was mutably borrowed
759- E0504 , // cannot move `..` into closure because it is borrowed
760863 E0505 , // cannot move out of `..` because it is borrowed
761864 E0508 , // cannot move out of type `..`, a non-copy fixed-size array
762865 E0524 , // two closures require unique access to `..` at the same time
0 commit comments