]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/diagnostics.rs
Rollup merge of #45098 - sunjay:breakingrustfmtrls, r=alexcrichton
[rust.git] / src / librustc_mir / diagnostics.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_snake_case)]
12
13 register_long_diagnostics! {
14
15 E0010: r##"
16 The value of statics and constants must be known at compile time, and they live
17 for the entire lifetime of a program. Creating a boxed value allocates memory on
18 the heap at runtime, and therefore cannot be done at compile time. Erroneous
19 code example:
20
21 ```compile_fail,E0010
22 #![feature(box_syntax)]
23
24 const CON : Box<i32> = box 0;
25 ```
26 "##,
27
28 E0013: r##"
29 Static and const variables can refer to other const variables. But a const
30 variable cannot refer to a static variable. For example, `Y` cannot refer to
31 `X` here:
32
33 ```compile_fail,E0013
34 static X: i32 = 42;
35 const Y: i32 = X;
36 ```
37
38 To fix this, the value can be extracted as a const and then used:
39
40 ```
41 const A: i32 = 42;
42 static X: i32 = A;
43 const Y: i32 = A;
44 ```
45 "##,
46
47 // FIXME(#24111) Change the language here when const fn stabilizes
48 E0015: r##"
49 The only functions that can be called in static or constant expressions are
50 `const` functions, and struct/enum constructors. `const` functions are only
51 available on a nightly compiler. Rust currently does not support more general
52 compile-time function execution.
53
54 ```
55 const FOO: Option<u8> = Some(1); // enum constructor
56 struct Bar {x: u8}
57 const BAR: Bar = Bar {x: 1}; // struct constructor
58 ```
59
60 See [RFC 911] for more details on the design of `const fn`s.
61
62 [RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
63 "##,
64
65 E0016: r##"
66 Blocks in constants may only contain items (such as constant, function
67 definition, etc...) and a tail expression. Erroneous code example:
68
69 ```compile_fail,E0016
70 const FOO: i32 = { let x = 0; x }; // 'x' isn't an item!
71 ```
72
73 To avoid it, you have to replace the non-item object:
74
75 ```
76 const FOO: i32 = { const X : i32 = 0; X };
77 ```
78 "##,
79
80 E0017: r##"
81 References in statics and constants may only refer to immutable values.
82 Erroneous code example:
83
84 ```compile_fail,E0017
85 static X: i32 = 1;
86 const C: i32 = 2;
87
88 // these three are not allowed:
89 const CR: &'static mut i32 = &mut C;
90 static STATIC_REF: &'static mut i32 = &mut X;
91 static CONST_REF: &'static mut i32 = &mut C;
92 ```
93
94 Statics are shared everywhere, and if they refer to mutable data one might
95 violate memory safety since holding multiple mutable references to shared data
96 is not allowed.
97
98 If you really want global mutable state, try using `static mut` or a global
99 `UnsafeCell`.
100 "##,
101
102 E0018: r##"
103
104 The value of static and constant integers must be known at compile time. You
105 can't cast a pointer to an integer because the address of a pointer can
106 vary.
107
108 For example, if you write:
109
110 ```compile_fail,E0018
111 static MY_STATIC: u32 = 42;
112 static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
113 static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
114 ```
115
116 Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However,
117 the address can change when the program is linked, as well as change
118 between different executions due to ASLR, and many linkers would
119 not be able to calculate the value of `WHAT`.
120
121 On the other hand, static and constant pointers can point either to
122 a known numeric address or to the address of a symbol.
123
124 ```
125 static MY_STATIC: u32 = 42;
126 static MY_STATIC_ADDR: &'static u32 = &MY_STATIC;
127 const CONST_ADDR: *const u8 = 0x5f3759df as *const u8;
128 ```
129
130 This does not pose a problem by itself because they can't be
131 accessed directly.
132 "##,
133
134 E0019: r##"
135 A function call isn't allowed in the const's initialization expression
136 because the expression's value must be known at compile-time. Erroneous code
137 example:
138
139 ```compile_fail
140 enum Test {
141     V1
142 }
143
144 impl Test {
145     fn test(&self) -> i32 {
146         12
147     }
148 }
149
150 fn main() {
151     const FOO: Test = Test::V1;
152
153     const A: i32 = FOO.test(); // You can't call Test::func() here!
154 }
155 ```
156
157 Remember: you can't use a function call inside a const's initialization
158 expression! However, you can totally use it anywhere else:
159
160 ```
161 enum Test {
162     V1
163 }
164
165 impl Test {
166     fn func(&self) -> i32 {
167         12
168     }
169 }
170
171 fn main() {
172     const FOO: Test = Test::V1;
173
174     FOO.func(); // here is good
175     let x = FOO.func(); // or even here!
176 }
177 ```
178 "##,
179
180 E0022: r##"
181 Constant functions are not allowed to mutate anything. Thus, binding to an
182 argument with a mutable pattern is not allowed. For example,
183
184 ```compile_fail
185 const fn foo(mut x: u8) {
186     // do stuff
187 }
188 ```
189
190 Is incorrect because the function body may not mutate `x`.
191
192 Remove any mutable bindings from the argument list to fix this error. In case
193 you need to mutate the argument, try lazily initializing a global variable
194 instead of using a `const fn`, or refactoring the code to a functional style to
195 avoid mutation if possible.
196 "##,
197
198 E0133: r##"
199 Unsafe code was used outside of an unsafe function or block.
200
201 Erroneous code example:
202
203 ```compile_fail,E0133
204 unsafe fn f() { return; } // This is the unsafe code
205
206 fn main() {
207     f(); // error: call to unsafe function requires unsafe function or block
208 }
209 ```
210
211 Using unsafe functionality is potentially dangerous and disallowed by safety
212 checks. Examples:
213
214 * Dereferencing raw pointers
215 * Calling functions via FFI
216 * Calling functions marked unsafe
217
218 These safety checks can be relaxed for a section of the code by wrapping the
219 unsafe instructions with an `unsafe` block. For instance:
220
221 ```
222 unsafe fn f() { return; }
223
224 fn main() {
225     unsafe { f(); } // ok!
226 }
227 ```
228
229 See also https://doc.rust-lang.org/book/first-edition/unsafe.html
230 "##,
231
232 E0373: r##"
233 This error occurs when an attempt is made to use data captured by a closure,
234 when that data may no longer exist. It's most commonly seen when attempting to
235 return a closure:
236
237 ```compile_fail,E0373
238 fn foo() -> Box<Fn(u32) -> u32> {
239     let x = 0u32;
240     Box::new(|y| x + y)
241 }
242 ```
243
244 Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
245 closed-over data by reference. This means that once `foo()` returns, `x` no
246 longer exists. An attempt to access `x` within the closure would thus be
247 unsafe.
248
249 Another situation where this might be encountered is when spawning threads:
250
251 ```compile_fail,E0373
252 fn foo() {
253     let x = 0u32;
254     let y = 1u32;
255
256     let thr = std::thread::spawn(|| {
257         x + y
258     });
259 }
260 ```
261
262 Since our new thread runs in parallel, the stack frame containing `x` and `y`
263 may well have disappeared by the time we try to use them. Even if we call
264 `thr.join()` within foo (which blocks until `thr` has completed, ensuring the
265 stack frame won't disappear), we will not succeed: the compiler cannot prove
266 that this behaviour is safe, and so won't let us do it.
267
268 The solution to this problem is usually to switch to using a `move` closure.
269 This approach moves (or copies, where possible) data into the closure, rather
270 than taking references to it. For example:
271
272 ```
273 fn foo() -> Box<Fn(u32) -> u32> {
274     let x = 0u32;
275     Box::new(move |y| x + y)
276 }
277 ```
278
279 Now that the closure has its own copy of the data, there's no need to worry
280 about safety.
281 "##,
282
283 E0381: r##"
284 It is not allowed to use or capture an uninitialized variable. For example:
285
286 ```compile_fail,E0381
287 fn main() {
288     let x: i32;
289     let y = x; // error, use of possibly uninitialized variable
290 }
291 ```
292
293 To fix this, ensure that any declared variables are initialized before being
294 used. Example:
295
296 ```
297 fn main() {
298     let x: i32 = 0;
299     let y = x; // ok!
300 }
301 ```
302 "##,
303
304 E0382: r##"
305 This error occurs when an attempt is made to use a variable after its contents
306 have been moved elsewhere. For example:
307
308 ```compile_fail,E0382
309 struct MyStruct { s: u32 }
310
311 fn main() {
312     let mut x = MyStruct{ s: 5u32 };
313     let y = x;
314     x.s = 6;
315     println!("{}", x.s);
316 }
317 ```
318
319 Since `MyStruct` is a type that is not marked `Copy`, the data gets moved out
320 of `x` when we set `y`. This is fundamental to Rust's ownership system: outside
321 of workarounds like `Rc`, a value cannot be owned by more than one variable.
322
323 Sometimes we don't need to move the value. Using a reference, we can let another
324 function borrow the value without changing its ownership. In the example below,
325 we don't actually have to move our string to `calculate_length`, we can give it
326 a reference to it with `&` instead.
327
328 ```
329 fn main() {
330     let s1 = String::from("hello");
331
332     let len = calculate_length(&s1);
333
334     println!("The length of '{}' is {}.", s1, len);
335 }
336
337 fn calculate_length(s: &String) -> usize {
338     s.len()
339 }
340 ```
341
342 A mutable reference can be created with `&mut`.
343
344 Sometimes we don't want a reference, but a duplicate. All types marked `Clone`
345 can be duplicated by calling `.clone()`. Subsequent changes to a clone do not
346 affect the original variable.
347
348 Most types in the standard library are marked `Clone`. The example below
349 demonstrates using `clone()` on a string. `s1` is first set to "many", and then
350 copied to `s2`. Then the first character of `s1` is removed, without affecting
351 `s2`. "any many" is printed to the console.
352
353 ```
354 fn main() {
355     let mut s1 = String::from("many");
356     let s2 = s1.clone();
357     s1.remove(0);
358     println!("{} {}", s1, s2);
359 }
360 ```
361
362 If we control the definition of a type, we can implement `Clone` on it ourselves
363 with `#[derive(Clone)]`.
364
365 Some types have no ownership semantics at all and are trivial to duplicate. An
366 example is `i32` and the other number types. We don't have to call `.clone()` to
367 clone them, because they are marked `Copy` in addition to `Clone`.  Implicit
368 cloning is more convienient in this case. We can mark our own types `Copy` if
369 all their members also are marked `Copy`.
370
371 In the example below, we implement a `Point` type. Because it only stores two
372 integers, we opt-out of ownership semantics with `Copy`. Then we can
373 `let p2 = p1` without `p1` being moved.
374
375 ```
376 #[derive(Copy, Clone)]
377 struct Point { x: i32, y: i32 }
378
379 fn main() {
380     let mut p1 = Point{ x: -1, y: 2 };
381     let p2 = p1;
382     p1.x = 1;
383     println!("p1: {}, {}", p1.x, p1.y);
384     println!("p2: {}, {}", p2.x, p2.y);
385 }
386 ```
387
388 Alternatively, if we don't control the struct's definition, or mutable shared
389 ownership is truly required, we can use `Rc` and `RefCell`:
390
391 ```
392 use std::cell::RefCell;
393 use std::rc::Rc;
394
395 struct MyStruct { s: u32 }
396
397 fn main() {
398     let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
399     let y = x.clone();
400     x.borrow_mut().s = 6;
401     println!("{}", x.borrow().s);
402 }
403 ```
404
405 With this approach, x and y share ownership of the data via the `Rc` (reference
406 count type). `RefCell` essentially performs runtime borrow checking: ensuring
407 that at most one writer or multiple readers can access the data at any one time.
408
409 If you wish to learn more about ownership in Rust, start with the chapter in the
410 Book:
411
412 https://doc.rust-lang.org/book/first-edition/ownership.html
413 "##,
414
415 E0383: r##"
416 This error occurs when an attempt is made to partially reinitialize a
417 structure that is currently uninitialized.
418
419 For example, this can happen when a drop has taken place:
420
421 ```compile_fail,E0383
422 struct Foo {
423     a: u32,
424 }
425 impl Drop for Foo {
426     fn drop(&mut self) { /* ... */ }
427 }
428
429 let mut x = Foo { a: 1 };
430 drop(x); // `x` is now uninitialized
431 x.a = 2; // error, partial reinitialization of uninitialized structure `t`
432 ```
433
434 This error can be fixed by fully reinitializing the structure in question:
435
436 ```
437 struct Foo {
438     a: u32,
439 }
440 impl Drop for Foo {
441     fn drop(&mut self) { /* ... */ }
442 }
443
444 let mut x = Foo { a: 1 };
445 drop(x);
446 x = Foo { a: 2 };
447 ```
448 "##,
449
450 E0384: r##"
451 This error occurs when an attempt is made to reassign an immutable variable.
452 For example:
453
454 ```compile_fail,E0384
455 fn main() {
456     let x = 3;
457     x = 5; // error, reassignment of immutable variable
458 }
459 ```
460
461 By default, variables in Rust are immutable. To fix this error, add the keyword
462 `mut` after the keyword `let` when declaring the variable. For example:
463
464 ```
465 fn main() {
466     let mut x = 3;
467     x = 5;
468 }
469 ```
470 "##,
471
472 /*E0386: r##"
473 This error occurs when an attempt is made to mutate the target of a mutable
474 reference stored inside an immutable container.
475
476 For example, this can happen when storing a `&mut` inside an immutable `Box`:
477
478 ```compile_fail,E0386
479 let mut x: i64 = 1;
480 let y: Box<_> = Box::new(&mut x);
481 **y = 2; // error, cannot assign to data in an immutable container
482 ```
483
484 This error can be fixed by making the container mutable:
485
486 ```
487 let mut x: i64 = 1;
488 let mut y: Box<_> = Box::new(&mut x);
489 **y = 2;
490 ```
491
492 It can also be fixed by using a type with interior mutability, such as `Cell`
493 or `RefCell`:
494
495 ```
496 use std::cell::Cell;
497
498 let x: i64 = 1;
499 let y: Box<Cell<_>> = Box::new(Cell::new(x));
500 y.set(2);
501 ```
502 "##,*/
503
504 E0387: r##"
505 This error occurs when an attempt is made to mutate or mutably reference data
506 that a closure has captured immutably. Examples of this error are shown below:
507
508 ```compile_fail,E0387
509 // Accepts a function or a closure that captures its environment immutably.
510 // Closures passed to foo will not be able to mutate their closed-over state.
511 fn foo<F: Fn()>(f: F) { }
512
513 // Attempts to mutate closed-over data. Error message reads:
514 // `cannot assign to data in a captured outer variable...`
515 fn mutable() {
516     let mut x = 0u32;
517     foo(|| x = 2);
518 }
519
520 // Attempts to take a mutable reference to closed-over data.  Error message
521 // reads: `cannot borrow data mutably in a captured outer variable...`
522 fn mut_addr() {
523     let mut x = 0u32;
524     foo(|| { let y = &mut x; });
525 }
526 ```
527
528 The problem here is that foo is defined as accepting a parameter of type `Fn`.
529 Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
530 they capture their context immutably.
531
532 If the definition of `foo` is under your control, the simplest solution is to
533 capture the data mutably. This can be done by defining `foo` to take FnMut
534 rather than Fn:
535
536 ```
537 fn foo<F: FnMut()>(f: F) { }
538 ```
539
540 Alternatively, we can consider using the `Cell` and `RefCell` types to achieve
541 interior mutability through a shared reference. Our example's `mutable`
542 function could be redefined as below:
543
544 ```
545 use std::cell::Cell;
546
547 fn foo<F: Fn()>(f: F) { }
548
549 fn mutable() {
550     let x = Cell::new(0u32);
551     foo(|| x.set(2));
552 }
553 ```
554
555 You can read more about cell types in the API documentation:
556
557 https://doc.rust-lang.org/std/cell/
558 "##,
559
560 E0388: r##"
561 E0388 was removed and is no longer issued.
562 "##,
563
564 E0389: r##"
565 An attempt was made to mutate data using a non-mutable reference. This
566 commonly occurs when attempting to assign to a non-mutable reference of a
567 mutable reference (`&(&mut T)`).
568
569 Example of erroneous code:
570
571 ```compile_fail,E0389
572 struct FancyNum {
573     num: u8,
574 }
575
576 fn main() {
577     let mut fancy = FancyNum{ num: 5 };
578     let fancy_ref = &(&mut fancy);
579     fancy_ref.num = 6; // error: cannot assign to data in a `&` reference
580     println!("{}", fancy_ref.num);
581 }
582 ```
583
584 Here, `&mut fancy` is mutable, but `&(&mut fancy)` is not. Creating an
585 immutable reference to a value borrows it immutably. There can be multiple
586 references of type `&(&mut T)` that point to the same value, so they must be
587 immutable to prevent multiple mutable references to the same value.
588
589 To fix this, either remove the outer reference:
590
591 ```
592 struct FancyNum {
593     num: u8,
594 }
595
596 fn main() {
597     let mut fancy = FancyNum{ num: 5 };
598
599     let fancy_ref = &mut fancy;
600     // `fancy_ref` is now &mut FancyNum, rather than &(&mut FancyNum)
601
602     fancy_ref.num = 6; // No error!
603
604     println!("{}", fancy_ref.num);
605 }
606 ```
607
608 Or make the outer reference mutable:
609
610 ```
611 struct FancyNum {
612     num: u8
613 }
614
615 fn main() {
616     let mut fancy = FancyNum{ num: 5 };
617
618     let fancy_ref = &mut (&mut fancy);
619     // `fancy_ref` is now &mut(&mut FancyNum), rather than &(&mut FancyNum)
620
621     fancy_ref.num = 6; // No error!
622
623     println!("{}", fancy_ref.num);
624 }
625 ```
626 "##,
627
628 E0394: r##"
629 A static was referred to by value by another static.
630
631 Erroneous code examples:
632
633 ```compile_fail,E0394
634 static A: u32 = 0;
635 static B: u32 = A; // error: cannot refer to other statics by value, use the
636                    //        address-of operator or a constant instead
637 ```
638
639 A static cannot be referred by value. To fix this issue, either use a
640 constant:
641
642 ```
643 const A: u32 = 0; // `A` is now a constant
644 static B: u32 = A; // ok!
645 ```
646
647 Or refer to `A` by reference:
648
649 ```
650 static A: u32 = 0;
651 static B: &'static u32 = &A; // ok!
652 ```
653 "##,
654
655 E0395: r##"
656 The value assigned to a constant scalar must be known at compile time,
657 which is not the case when comparing raw pointers.
658
659 Erroneous code example:
660
661 ```compile_fail,E0395
662 static FOO: i32 = 42;
663 static BAR: i32 = 42;
664
665 static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
666 // error: raw pointers cannot be compared in statics!
667 ```
668
669 The address assigned by the linker to `FOO` and `BAR` may or may not
670 be identical, so the value of `BAZ` can't be determined.
671
672 If you want to do the comparison, please do it at run-time.
673
674 For example:
675
676 ```
677 static FOO: i32 = 42;
678 static BAR: i32 = 42;
679
680 let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
681 // baz isn't a constant expression so it's ok
682 ```
683 "##,
684
685 E0161: r##"
686 A value was moved. However, its size was not known at compile time, and only
687 values of a known size can be moved.
688
689 Erroneous code example:
690
691 ```compile_fail
692 #![feature(box_syntax)]
693
694 fn main() {
695     let array: &[isize] = &[1, 2, 3];
696     let _x: Box<[isize]> = box *array;
697     // error: cannot move a value of type [isize]: the size of [isize] cannot
698     //        be statically determined
699 }
700 ```
701
702 In Rust, you can only move a value when its size is known at compile time.
703
704 To work around this restriction, consider "hiding" the value behind a reference:
705 either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
706 it around as usual. Example:
707
708 ```
709 #![feature(box_syntax)]
710
711 fn main() {
712     let array: &[isize] = &[1, 2, 3];
713     let _x: Box<&[isize]> = box array; // ok!
714 }
715 ```
716 "##,
717
718 E0396: r##"
719 The value behind a raw pointer can't be determined at compile-time
720 (or even link-time), which means it can't be used in a constant
721 expression. Erroneous code example:
722
723 ```compile_fail,E0396
724 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
725
726 const VALUE: u8 = unsafe { *REG_ADDR };
727 // error: raw pointers cannot be dereferenced in constants
728 ```
729
730 A possible fix is to dereference your pointer at some point in run-time.
731
732 For example:
733
734 ```
735 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
736
737 let reg_value = unsafe { *REG_ADDR };
738 ```
739 "##,
740
741 E0492: r##"
742 A borrow of a constant containing interior mutability was attempted. Erroneous
743 code example:
744
745 ```compile_fail,E0492
746 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
747
748 const A: AtomicUsize = ATOMIC_USIZE_INIT;
749 static B: &'static AtomicUsize = &A;
750 // error: cannot borrow a constant which may contain interior mutability,
751 //        create a static instead
752 ```
753
754 A `const` represents a constant value that should never change. If one takes
755 a `&` reference to the constant, then one is taking a pointer to some memory
756 location containing the value. Normally this is perfectly fine: most values
757 can't be changed via a shared `&` pointer, but interior mutability would allow
758 it. That is, a constant value could be mutated. On the other hand, a `static` is
759 explicitly a single memory location, which can be mutated at will.
760
761 So, in order to solve this error, either use statics which are `Sync`:
762
763 ```
764 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
765
766 static A: AtomicUsize = ATOMIC_USIZE_INIT;
767 static B: &'static AtomicUsize = &A; // ok!
768 ```
769
770 You can also have this error while using a cell type:
771
772 ```compile_fail,E0492
773 #![feature(const_cell_new)]
774
775 use std::cell::Cell;
776
777 const A: Cell<usize> = Cell::new(1);
778 const B: &'static Cell<usize> = &A;
779 // error: cannot borrow a constant which may contain interior mutability,
780 //        create a static instead
781
782 // or:
783 struct C { a: Cell<usize> }
784
785 const D: C = C { a: Cell::new(1) };
786 const E: &'static Cell<usize> = &D.a; // error
787
788 // or:
789 const F: &'static C = &D; // error
790 ```
791
792 This is because cell types do operations that are not thread-safe. Due to this,
793 they don't implement Sync and thus can't be placed in statics. In this
794 case, `StaticMutex` would work just fine, but it isn't stable yet:
795 https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
796
797 However, if you still wish to use these types, you can achieve this by an unsafe
798 wrapper:
799
800 ```
801 #![feature(const_cell_new)]
802
803 use std::cell::Cell;
804 use std::marker::Sync;
805
806 struct NotThreadSafe<T> {
807     value: Cell<T>,
808 }
809
810 unsafe impl<T> Sync for NotThreadSafe<T> {}
811
812 static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
813 static B: &'static NotThreadSafe<usize> = &A; // ok!
814 ```
815
816 Remember this solution is unsafe! You will have to ensure that accesses to the
817 cell are synchronized.
818 "##,
819
820 E0494: r##"
821 A reference of an interior static was assigned to another const/static.
822 Erroneous code example:
823
824 ```compile_fail,E0494
825 struct Foo {
826     a: u32
827 }
828
829 static S : Foo = Foo { a : 0 };
830 static A : &'static u32 = &S.a;
831 // error: cannot refer to the interior of another static, use a
832 //        constant instead
833 ```
834
835 The "base" variable has to be a const if you want another static/const variable
836 to refer to one of its fields. Example:
837
838 ```
839 struct Foo {
840     a: u32
841 }
842
843 const S : Foo = Foo { a : 0 };
844 static A : &'static u32 = &S.a; // ok!
845 ```
846 "##,
847
848 E0499: r##"
849 A variable was borrowed as mutable more than once. Erroneous code example:
850
851 ```compile_fail,E0499
852 let mut i = 0;
853 let mut x = &mut i;
854 let mut a = &mut i;
855 // error: cannot borrow `i` as mutable more than once at a time
856 ```
857
858 Please note that in rust, you can either have many immutable references, or one
859 mutable reference. Take a look at
860 https://doc.rust-lang.org/stable/book/references-and-borrowing.html for more
861 information. Example:
862
863
864 ```
865 let mut i = 0;
866 let mut x = &mut i; // ok!
867
868 // or:
869 let mut i = 0;
870 let a = &i; // ok!
871 let b = &i; // still ok!
872 let c = &i; // still ok!
873 ```
874 "##,
875
876 E0500: r##"
877 A borrowed variable was used in another closure. Example of erroneous code:
878
879 ```compile_fail
880 fn you_know_nothing(jon_snow: &mut i32) {
881     let nights_watch = || {
882         *jon_snow = 2;
883     };
884     let starks = || {
885         *jon_snow = 3; // error: closure requires unique access to `jon_snow`
886                        //        but it is already borrowed
887     };
888 }
889 ```
890
891 In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
892 cannot be borrowed by the `starks` closure at the same time. To fix this issue,
893 you can put the closure in its own scope:
894
895 ```
896 fn you_know_nothing(jon_snow: &mut i32) {
897     {
898         let nights_watch = || {
899             *jon_snow = 2;
900         };
901     } // At this point, `jon_snow` is free.
902     let starks = || {
903         *jon_snow = 3;
904     };
905 }
906 ```
907
908 Or, if the type implements the `Clone` trait, you can clone it between
909 closures:
910
911 ```
912 fn you_know_nothing(jon_snow: &mut i32) {
913     let mut jon_copy = jon_snow.clone();
914     let nights_watch = || {
915         jon_copy = 2;
916     };
917     let starks = || {
918         *jon_snow = 3;
919     };
920 }
921 ```
922 "##,
923
924 E0501: r##"
925 This error indicates that a mutable variable is being used while it is still
926 captured by a closure. Because the closure has borrowed the variable, it is not
927 available for use until the closure goes out of scope.
928
929 Note that a capture will either move or borrow a variable, but in this
930 situation, the closure is borrowing the variable. Take a look at
931 http://rustbyexample.com/fn/closures/capture.html for more information about
932 capturing.
933
934 Example of erroneous code:
935
936 ```compile_fail,E0501
937 fn inside_closure(x: &mut i32) {
938     // Actions which require unique access
939 }
940
941 fn outside_closure(x: &mut i32) {
942     // Actions which require unique access
943 }
944
945 fn foo(a: &mut i32) {
946     let bar = || {
947         inside_closure(a)
948     };
949     outside_closure(a); // error: cannot borrow `*a` as mutable because previous
950                         //        closure requires unique access.
951 }
952 ```
953
954 To fix this error, you can place the closure in its own scope:
955
956 ```
957 fn inside_closure(x: &mut i32) {}
958 fn outside_closure(x: &mut i32) {}
959
960 fn foo(a: &mut i32) {
961     {
962         let bar = || {
963             inside_closure(a)
964         };
965     } // borrow on `a` ends.
966     outside_closure(a); // ok!
967 }
968 ```
969
970 Or you can pass the variable as a parameter to the closure:
971
972 ```
973 fn inside_closure(x: &mut i32) {}
974 fn outside_closure(x: &mut i32) {}
975
976 fn foo(a: &mut i32) {
977     let bar = |s: &mut i32| {
978         inside_closure(s)
979     };
980     outside_closure(a);
981     bar(a);
982 }
983 ```
984
985 It may be possible to define the closure later:
986
987 ```
988 fn inside_closure(x: &mut i32) {}
989 fn outside_closure(x: &mut i32) {}
990
991 fn foo(a: &mut i32) {
992     outside_closure(a);
993     let bar = || {
994         inside_closure(a)
995     };
996 }
997 ```
998 "##,
999
1000 E0502: r##"
1001 This error indicates that you are trying to borrow a variable as mutable when it
1002 has already been borrowed as immutable.
1003
1004 Example of erroneous code:
1005
1006 ```compile_fail,E0502
1007 fn bar(x: &mut i32) {}
1008 fn foo(a: &mut i32) {
1009     let ref y = a; // a is borrowed as immutable.
1010     bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
1011             //        as immutable
1012 }
1013 ```
1014
1015 To fix this error, ensure that you don't have any other references to the
1016 variable before trying to access it mutably:
1017
1018 ```
1019 fn bar(x: &mut i32) {}
1020 fn foo(a: &mut i32) {
1021     bar(a);
1022     let ref y = a; // ok!
1023 }
1024 ```
1025
1026 For more information on the rust ownership system, take a look at
1027 https://doc.rust-lang.org/stable/book/references-and-borrowing.html.
1028 "##,
1029
1030 E0503: r##"
1031 A value was used after it was mutably borrowed.
1032
1033 Example of erroneous code:
1034
1035 ```compile_fail,E0503
1036 fn main() {
1037     let mut value = 3;
1038     // Create a mutable borrow of `value`. This borrow
1039     // lives until the end of this function.
1040     let _borrow = &mut value;
1041     let _sum = value + 1; // error: cannot use `value` because
1042                           //        it was mutably borrowed
1043 }
1044 ```
1045
1046 In this example, `value` is mutably borrowed by `borrow` and cannot be
1047 used to calculate `sum`. This is not possible because this would violate
1048 Rust's mutability rules.
1049
1050 You can fix this error by limiting the scope of the borrow:
1051
1052 ```
1053 fn main() {
1054     let mut value = 3;
1055     // By creating a new block, you can limit the scope
1056     // of the reference.
1057     {
1058         let _borrow = &mut value; // Use `_borrow` inside this block.
1059     }
1060     // The block has ended and with it the borrow.
1061     // You can now use `value` again.
1062     let _sum = value + 1;
1063 }
1064 ```
1065
1066 Or by cloning `value` before borrowing it:
1067
1068 ```
1069 fn main() {
1070     let mut value = 3;
1071     // We clone `value`, creating a copy.
1072     let value_cloned = value.clone();
1073     // The mutable borrow is a reference to `value` and
1074     // not to `value_cloned`...
1075     let _borrow = &mut value;
1076     // ... which means we can still use `value_cloned`,
1077     let _sum = value_cloned + 1;
1078     // even though the borrow only ends here.
1079 }
1080 ```
1081
1082 You can find more information about borrowing in the rust-book:
1083 http://doc.rust-lang.org/stable/book/references-and-borrowing.html
1084 "##,
1085
1086 E0504: r##"
1087 This error occurs when an attempt is made to move a borrowed variable into a
1088 closure.
1089
1090 Example of erroneous code:
1091
1092 ```compile_fail,E0504
1093 struct FancyNum {
1094     num: u8,
1095 }
1096
1097 fn main() {
1098     let fancy_num = FancyNum { num: 5 };
1099     let fancy_ref = &fancy_num;
1100
1101     let x = move || {
1102         println!("child function: {}", fancy_num.num);
1103         // error: cannot move `fancy_num` into closure because it is borrowed
1104     };
1105
1106     x();
1107     println!("main function: {}", fancy_ref.num);
1108 }
1109 ```
1110
1111 Here, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into
1112 the closure `x`. There is no way to move a value into a closure while it is
1113 borrowed, as that would invalidate the borrow.
1114
1115 If the closure can't outlive the value being moved, try using a reference
1116 rather than moving:
1117
1118 ```
1119 struct FancyNum {
1120     num: u8,
1121 }
1122
1123 fn main() {
1124     let fancy_num = FancyNum { num: 5 };
1125     let fancy_ref = &fancy_num;
1126
1127     let x = move || {
1128         // fancy_ref is usable here because it doesn't move `fancy_num`
1129         println!("child function: {}", fancy_ref.num);
1130     };
1131
1132     x();
1133
1134     println!("main function: {}", fancy_num.num);
1135 }
1136 ```
1137
1138 If the value has to be borrowed and then moved, try limiting the lifetime of
1139 the borrow using a scoped block:
1140
1141 ```
1142 struct FancyNum {
1143     num: u8,
1144 }
1145
1146 fn main() {
1147     let fancy_num = FancyNum { num: 5 };
1148
1149     {
1150         let fancy_ref = &fancy_num;
1151         println!("main function: {}", fancy_ref.num);
1152         // `fancy_ref` goes out of scope here
1153     }
1154
1155     let x = move || {
1156         // `fancy_num` can be moved now (no more references exist)
1157         println!("child function: {}", fancy_num.num);
1158     };
1159
1160     x();
1161 }
1162 ```
1163
1164 If the lifetime of a reference isn't enough, such as in the case of threading,
1165 consider using an `Arc` to create a reference-counted value:
1166
1167 ```
1168 use std::sync::Arc;
1169 use std::thread;
1170
1171 struct FancyNum {
1172     num: u8,
1173 }
1174
1175 fn main() {
1176     let fancy_ref1 = Arc::new(FancyNum { num: 5 });
1177     let fancy_ref2 = fancy_ref1.clone();
1178
1179     let x = thread::spawn(move || {
1180         // `fancy_ref1` can be moved and has a `'static` lifetime
1181         println!("child thread: {}", fancy_ref1.num);
1182     });
1183
1184     x.join().expect("child thread should finish");
1185     println!("main thread: {}", fancy_ref2.num);
1186 }
1187 ```
1188 "##,
1189
1190 E0505: r##"
1191 A value was moved out while it was still borrowed.
1192
1193 Erroneous code example:
1194
1195 ```compile_fail,E0505
1196 struct Value {}
1197
1198 fn eat(val: Value) {}
1199
1200 fn main() {
1201     let x = Value{};
1202     {
1203         let _ref_to_val: &Value = &x;
1204         eat(x);
1205     }
1206 }
1207 ```
1208
1209 Here, the function `eat` takes the ownership of `x`. However,
1210 `x` cannot be moved because it was borrowed to `_ref_to_val`.
1211 To fix that you can do few different things:
1212
1213 * Try to avoid moving the variable.
1214 * Release borrow before move.
1215 * Implement the `Copy` trait on the type.
1216
1217 Examples:
1218
1219 ```
1220 struct Value {}
1221
1222 fn eat(val: &Value) {}
1223
1224 fn main() {
1225     let x = Value{};
1226     {
1227         let _ref_to_val: &Value = &x;
1228         eat(&x); // pass by reference, if it's possible
1229     }
1230 }
1231 ```
1232
1233 Or:
1234
1235 ```
1236 struct Value {}
1237
1238 fn eat(val: Value) {}
1239
1240 fn main() {
1241     let x = Value{};
1242     {
1243         let _ref_to_val: &Value = &x;
1244     }
1245     eat(x); // release borrow and then move it.
1246 }
1247 ```
1248
1249 Or:
1250
1251 ```
1252 #[derive(Clone, Copy)] // implement Copy trait
1253 struct Value {}
1254
1255 fn eat(val: Value) {}
1256
1257 fn main() {
1258     let x = Value{};
1259     {
1260         let _ref_to_val: &Value = &x;
1261         eat(x); // it will be copied here.
1262     }
1263 }
1264 ```
1265
1266 You can find more information about borrowing in the rust-book:
1267 http://doc.rust-lang.org/stable/book/references-and-borrowing.html
1268 "##,
1269
1270 E0506: r##"
1271 This error occurs when an attempt is made to assign to a borrowed value.
1272
1273 Example of erroneous code:
1274
1275 ```compile_fail,E0506
1276 struct FancyNum {
1277     num: u8,
1278 }
1279
1280 fn main() {
1281     let mut fancy_num = FancyNum { num: 5 };
1282     let fancy_ref = &fancy_num;
1283     fancy_num = FancyNum { num: 6 };
1284     // error: cannot assign to `fancy_num` because it is borrowed
1285
1286     println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
1287 }
1288 ```
1289
1290 Because `fancy_ref` still holds a reference to `fancy_num`, `fancy_num` can't
1291 be assigned to a new value as it would invalidate the reference.
1292
1293 Alternatively, we can move out of `fancy_num` into a second `fancy_num`:
1294
1295 ```
1296 struct FancyNum {
1297     num: u8,
1298 }
1299
1300 fn main() {
1301     let mut fancy_num = FancyNum { num: 5 };
1302     let moved_num = fancy_num;
1303     fancy_num = FancyNum { num: 6 };
1304
1305     println!("Num: {}, Moved num: {}", fancy_num.num, moved_num.num);
1306 }
1307 ```
1308
1309 If the value has to be borrowed, try limiting the lifetime of the borrow using
1310 a scoped block:
1311
1312 ```
1313 struct FancyNum {
1314     num: u8,
1315 }
1316
1317 fn main() {
1318     let mut fancy_num = FancyNum { num: 5 };
1319
1320     {
1321         let fancy_ref = &fancy_num;
1322         println!("Ref: {}", fancy_ref.num);
1323     }
1324
1325     // Works because `fancy_ref` is no longer in scope
1326     fancy_num = FancyNum { num: 6 };
1327     println!("Num: {}", fancy_num.num);
1328 }
1329 ```
1330
1331 Or by moving the reference into a function:
1332
1333 ```
1334 struct FancyNum {
1335     num: u8,
1336 }
1337
1338 fn main() {
1339     let mut fancy_num = FancyNum { num: 5 };
1340
1341     print_fancy_ref(&fancy_num);
1342
1343     // Works because function borrow has ended
1344     fancy_num = FancyNum { num: 6 };
1345     println!("Num: {}", fancy_num.num);
1346 }
1347
1348 fn print_fancy_ref(fancy_ref: &FancyNum){
1349     println!("Ref: {}", fancy_ref.num);
1350 }
1351 ```
1352 "##,
1353
1354 E0507: r##"
1355 You tried to move out of a value which was borrowed. Erroneous code example:
1356
1357 ```compile_fail,E0507
1358 use std::cell::RefCell;
1359
1360 struct TheDarkKnight;
1361
1362 impl TheDarkKnight {
1363     fn nothing_is_true(self) {}
1364 }
1365
1366 fn main() {
1367     let x = RefCell::new(TheDarkKnight);
1368
1369     x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
1370 }
1371 ```
1372
1373 Here, the `nothing_is_true` method takes the ownership of `self`. However,
1374 `self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
1375 which is a borrow of the content owned by the `RefCell`. To fix this error,
1376 you have three choices:
1377
1378 * Try to avoid moving the variable.
1379 * Somehow reclaim the ownership.
1380 * Implement the `Copy` trait on the type.
1381
1382 Examples:
1383
1384 ```
1385 use std::cell::RefCell;
1386
1387 struct TheDarkKnight;
1388
1389 impl TheDarkKnight {
1390     fn nothing_is_true(&self) {} // First case, we don't take ownership
1391 }
1392
1393 fn main() {
1394     let x = RefCell::new(TheDarkKnight);
1395
1396     x.borrow().nothing_is_true(); // ok!
1397 }
1398 ```
1399
1400 Or:
1401
1402 ```
1403 use std::cell::RefCell;
1404
1405 struct TheDarkKnight;
1406
1407 impl TheDarkKnight {
1408     fn nothing_is_true(self) {}
1409 }
1410
1411 fn main() {
1412     let x = RefCell::new(TheDarkKnight);
1413     let x = x.into_inner(); // we get back ownership
1414
1415     x.nothing_is_true(); // ok!
1416 }
1417 ```
1418
1419 Or:
1420
1421 ```
1422 use std::cell::RefCell;
1423
1424 #[derive(Clone, Copy)] // we implement the Copy trait
1425 struct TheDarkKnight;
1426
1427 impl TheDarkKnight {
1428     fn nothing_is_true(self) {}
1429 }
1430
1431 fn main() {
1432     let x = RefCell::new(TheDarkKnight);
1433
1434     x.borrow().nothing_is_true(); // ok!
1435 }
1436 ```
1437
1438 Moving a member out of a mutably borrowed struct will also cause E0507 error:
1439
1440 ```compile_fail,E0507
1441 struct TheDarkKnight;
1442
1443 impl TheDarkKnight {
1444     fn nothing_is_true(self) {}
1445 }
1446
1447 struct Batcave {
1448     knight: TheDarkKnight
1449 }
1450
1451 fn main() {
1452     let mut cave = Batcave {
1453         knight: TheDarkKnight
1454     };
1455     let borrowed = &mut cave;
1456
1457     borrowed.knight.nothing_is_true(); // E0507
1458 }
1459 ```
1460
1461 It is fine only if you put something back. `mem::replace` can be used for that:
1462
1463 ```
1464 # struct TheDarkKnight;
1465 # impl TheDarkKnight { fn nothing_is_true(self) {} }
1466 # struct Batcave { knight: TheDarkKnight }
1467 use std::mem;
1468
1469 let mut cave = Batcave {
1470     knight: TheDarkKnight
1471 };
1472 let borrowed = &mut cave;
1473
1474 mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
1475 ```
1476
1477 You can find more information about borrowing in the rust-book:
1478 http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html
1479 "##,
1480
1481 E0508: r##"
1482 A value was moved out of a non-copy fixed-size array.
1483
1484 Example of erroneous code:
1485
1486 ```compile_fail,E0508
1487 struct NonCopy;
1488
1489 fn main() {
1490     let array = [NonCopy; 1];
1491     let _value = array[0]; // error: cannot move out of type `[NonCopy; 1]`,
1492                            //        a non-copy fixed-size array
1493 }
1494 ```
1495
1496 The first element was moved out of the array, but this is not
1497 possible because `NonCopy` does not implement the `Copy` trait.
1498
1499 Consider borrowing the element instead of moving it:
1500
1501 ```
1502 struct NonCopy;
1503
1504 fn main() {
1505     let array = [NonCopy; 1];
1506     let _value = &array[0]; // Borrowing is allowed, unlike moving.
1507 }
1508 ```
1509
1510 Alternatively, if your type implements `Clone` and you need to own the value,
1511 consider borrowing and then cloning:
1512
1513 ```
1514 #[derive(Clone)]
1515 struct NonCopy;
1516
1517 fn main() {
1518     let array = [NonCopy; 1];
1519     // Now you can clone the array element.
1520     let _value = array[0].clone();
1521 }
1522 ```
1523 "##,
1524
1525 E0509: r##"
1526 This error occurs when an attempt is made to move out of a value whose type
1527 implements the `Drop` trait.
1528
1529 Example of erroneous code:
1530
1531 ```compile_fail,E0509
1532 struct FancyNum {
1533     num: usize
1534 }
1535
1536 struct DropStruct {
1537     fancy: FancyNum
1538 }
1539
1540 impl Drop for DropStruct {
1541     fn drop(&mut self) {
1542         // Destruct DropStruct, possibly using FancyNum
1543     }
1544 }
1545
1546 fn main() {
1547     let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
1548     let fancy_field = drop_struct.fancy; // Error E0509
1549     println!("Fancy: {}", fancy_field.num);
1550     // implicit call to `drop_struct.drop()` as drop_struct goes out of scope
1551 }
1552 ```
1553
1554 Here, we tried to move a field out of a struct of type `DropStruct` which
1555 implements the `Drop` trait. However, a struct cannot be dropped if one or
1556 more of its fields have been moved.
1557
1558 Structs implementing the `Drop` trait have an implicit destructor that gets
1559 called when they go out of scope. This destructor may use the fields of the
1560 struct, so moving out of the struct could make it impossible to run the
1561 destructor. Therefore, we must think of all values whose type implements the
1562 `Drop` trait as single units whose fields cannot be moved.
1563
1564 This error can be fixed by creating a reference to the fields of a struct,
1565 enum, or tuple using the `ref` keyword:
1566
1567 ```
1568 struct FancyNum {
1569     num: usize
1570 }
1571
1572 struct DropStruct {
1573     fancy: FancyNum
1574 }
1575
1576 impl Drop for DropStruct {
1577     fn drop(&mut self) {
1578         // Destruct DropStruct, possibly using FancyNum
1579     }
1580 }
1581
1582 fn main() {
1583     let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
1584     let ref fancy_field = drop_struct.fancy; // No more errors!
1585     println!("Fancy: {}", fancy_field.num);
1586     // implicit call to `drop_struct.drop()` as drop_struct goes out of scope
1587 }
1588 ```
1589
1590 Note that this technique can also be used in the arms of a match expression:
1591
1592 ```
1593 struct FancyNum {
1594     num: usize
1595 }
1596
1597 enum DropEnum {
1598     Fancy(FancyNum)
1599 }
1600
1601 impl Drop for DropEnum {
1602     fn drop(&mut self) {
1603         // Destruct DropEnum, possibly using FancyNum
1604     }
1605 }
1606
1607 fn main() {
1608     // Creates and enum of type `DropEnum`, which implements `Drop`
1609     let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
1610     match drop_enum {
1611         // Creates a reference to the inside of `DropEnum::Fancy`
1612         DropEnum::Fancy(ref fancy_field) => // No error!
1613             println!("It was fancy-- {}!", fancy_field.num),
1614     }
1615     // implicit call to `drop_enum.drop()` as drop_enum goes out of scope
1616 }
1617 ```
1618 "##,
1619
1620 E0595: r##"
1621 Closures cannot mutate immutable captured variables.
1622
1623 Erroneous code example:
1624
1625 ```compile_fail,E0595
1626 let x = 3; // error: closure cannot assign to immutable local variable `x`
1627 let mut c = || { x += 1 };
1628 ```
1629
1630 Make the variable binding mutable:
1631
1632 ```
1633 let mut x = 3; // ok!
1634 let mut c = || { x += 1 };
1635 ```
1636 "##,
1637
1638 E0596: r##"
1639 This error occurs because you tried to mutably borrow a non-mutable variable.
1640
1641 Example of erroneous code:
1642
1643 ```compile_fail,E0596
1644 let x = 1;
1645 let y = &mut x; // error: cannot borrow mutably
1646 ```
1647
1648 In here, `x` isn't mutable, so when we try to mutably borrow it in `y`, it
1649 fails. To fix this error, you need to make `x` mutable:
1650
1651 ```
1652 let mut x = 1;
1653 let y = &mut x; // ok!
1654 ```
1655 "##,
1656
1657 E0597: r##"
1658 This error occurs because a borrow was made inside a variable which has a
1659 greater lifetime than the borrowed one.
1660
1661 Example of erroneous code:
1662
1663 ```compile_fail,E0597
1664 struct Foo<'a> {
1665     x: Option<&'a u32>,
1666 }
1667
1668 let mut x = Foo { x: None };
1669 let y = 0;
1670 x.x = Some(&y); // error: `y` does not live long enough
1671 ```
1672
1673 In here, `x` is created before `y` and therefore has a greater lifetime. Always
1674 keep in mind that values in a scope are dropped in the opposite order they are
1675 created. So to fix the previous example, just make the `y` lifetime greater than
1676 the `x`'s one:
1677
1678 ```
1679 struct Foo<'a> {
1680     x: Option<&'a u32>,
1681 }
1682
1683 let y = 0;
1684 let mut x = Foo { x: None };
1685 x.x = Some(&y);
1686 ```
1687 "##,
1688
1689 E0626: r##"
1690 This error occurs because a borrow in a generator persists across a
1691 yield point.
1692
1693 ```compile_fail,E0626
1694 # #![feature(generators, generator_trait)]
1695 # use std::ops::Generator;
1696 let mut b = || {
1697     let a = &String::new(); // <-- This borrow...
1698     yield (); // ...is still in scope here, when the yield occurs.
1699     println!("{}", a);
1700 };
1701 b.resume();
1702 ```
1703
1704 At present, it is not permitted to have a yield that occurs while a
1705 borrow is still in scope. To resolve this error, the borrow must
1706 either be "contained" to a smaller scope that does not overlap the
1707 yield or else eliminated in another way. So, for example, we might
1708 resolve the previous example by removing the borrow and just storing
1709 the integer by value:
1710
1711 ```
1712 # #![feature(generators, generator_trait)]
1713 # use std::ops::Generator;
1714 let mut b = || {
1715     let a = 3;
1716     yield ();
1717     println!("{}", a);
1718 };
1719 b.resume();
1720 ```
1721
1722 This is a very simple case, of course. In more complex cases, we may
1723 wish to have more than one reference to the value that was borrowed --
1724 in those cases, something like the `Rc` or `Arc` types may be useful.
1725
1726 This error also frequently arises with iteration:
1727
1728 ```compile_fail,E0626
1729 # #![feature(generators, generator_trait)]
1730 # use std::ops::Generator;
1731 let mut b = || {
1732   let v = vec![1,2,3];
1733   for &x in &v { // <-- borrow of `v` is still in scope...
1734     yield x; // ...when this yield occurs.
1735   }
1736 };
1737 b.resume();
1738 ```
1739
1740 Such cases can sometimes be resolved by iterating "by value" (or using
1741 `into_iter()`) to avoid borrowing:
1742
1743 ```
1744 # #![feature(generators, generator_trait)]
1745 # use std::ops::Generator;
1746 let mut b = || {
1747   let v = vec![1,2,3];
1748   for x in v { // <-- Take ownership of the values instead!
1749     yield x; // <-- Now yield is OK.
1750   }
1751 };
1752 b.resume();
1753 ```
1754
1755 If taking ownership is not an option, using indices can work too:
1756
1757 ```
1758 # #![feature(generators, generator_trait)]
1759 # use std::ops::Generator;
1760 let mut b = || {
1761   let v = vec![1,2,3];
1762   let len = v.len(); // (*)
1763   for i in 0..len {
1764     let x = v[i]; // (*)
1765     yield x; // <-- Now yield is OK.
1766   }
1767 };
1768 b.resume();
1769
1770 // (*) -- Unfortunately, these temporaries are currently required.
1771 // See <https://github.com/rust-lang/rust/issues/43122>.
1772 ```
1773 "##,
1774
1775 }
1776
1777 register_diagnostics! {
1778 //    E0385, // {} in an aliasable location
1779     E0493, // destructors cannot be evaluated at compile-time
1780     E0524, // two closures require unique access to `..` at the same time
1781     E0526, // shuffle indices are not constant
1782     E0594, // cannot assign to {}
1783     E0598, // lifetime of {} is too short to guarantee its contents can be...
1784     E0625, // thread-local statics cannot be accessed at compile-time
1785 }