@@ -386,6 +386,109 @@ fn foo(a: &mut i32) {
386386 let bar = || {
387387 inside_closure(a)
388388 };
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);
389492}
390493```
391494"## ,
@@ -514,7 +617,6 @@ register_diagnostics! {
514617 E0500 , // closure requires unique access to `..` but .. is already borrowed
515618 E0502 , // cannot borrow `..`.. as .. because .. is also borrowed as ...
516619 E0503 , // cannot use `..` because it was mutably borrowed
517- E0504 , // cannot move `..` into closure because it is borrowed
518620 E0505 , // cannot move out of `..` because it is borrowed
519621 E0506 , // cannot assign to `..` because it is borrowed
520622 E0508 , // cannot move out of type `..`, a non-copy fixed-size array
0 commit comments