]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/diagnostics.rs
Rollup merge of #44562 - eddyb:ugh-rustdoc, r=nikomatsakis
[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 E0381: r##"
199 It is not allowed to use or capture an uninitialized variable. For example:
200
201 ```compile_fail,E0381
202 fn main() {
203     let x: i32;
204     let y = x; // error, use of possibly uninitialized variable
205 }
206 ```
207
208 To fix this, ensure that any declared variables are initialized before being
209 used. Example:
210
211 ```
212 fn main() {
213     let x: i32 = 0;
214     let y = x; // ok!
215 }
216 ```
217 "##,
218
219 E0384: r##"
220 This error occurs when an attempt is made to reassign an immutable variable.
221 For example:
222
223 ```compile_fail,E0384
224 fn main() {
225     let x = 3;
226     x = 5; // error, reassignment of immutable variable
227 }
228 ```
229
230 By default, variables in Rust are immutable. To fix this error, add the keyword
231 `mut` after the keyword `let` when declaring the variable. For example:
232
233 ```
234 fn main() {
235     let mut x = 3;
236     x = 5;
237 }
238 ```
239 "##,
240
241
242 E0394: r##"
243 A static was referred to by value by another static.
244
245 Erroneous code examples:
246
247 ```compile_fail,E0394
248 static A: u32 = 0;
249 static B: u32 = A; // error: cannot refer to other statics by value, use the
250                    //        address-of operator or a constant instead
251 ```
252
253 A static cannot be referred by value. To fix this issue, either use a
254 constant:
255
256 ```
257 const A: u32 = 0; // `A` is now a constant
258 static B: u32 = A; // ok!
259 ```
260
261 Or refer to `A` by reference:
262
263 ```
264 static A: u32 = 0;
265 static B: &'static u32 = &A; // ok!
266 ```
267 "##,
268
269 E0395: r##"
270 The value assigned to a constant scalar must be known at compile time,
271 which is not the case when comparing raw pointers.
272
273 Erroneous code example:
274
275 ```compile_fail,E0395
276 static FOO: i32 = 42;
277 static BAR: i32 = 42;
278
279 static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
280 // error: raw pointers cannot be compared in statics!
281 ```
282
283 The address assigned by the linker to `FOO` and `BAR` may or may not
284 be identical, so the value of `BAZ` can't be determined.
285
286 If you want to do the comparison, please do it at run-time.
287
288 For example:
289
290 ```
291 static FOO: i32 = 42;
292 static BAR: i32 = 42;
293
294 let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
295 // baz isn't a constant expression so it's ok
296 ```
297 "##,
298
299 E0161: r##"
300 A value was moved. However, its size was not known at compile time, and only
301 values of a known size can be moved.
302
303 Erroneous code example:
304
305 ```compile_fail
306 #![feature(box_syntax)]
307
308 fn main() {
309     let array: &[isize] = &[1, 2, 3];
310     let _x: Box<[isize]> = box *array;
311     // error: cannot move a value of type [isize]: the size of [isize] cannot
312     //        be statically determined
313 }
314 ```
315
316 In Rust, you can only move a value when its size is known at compile time.
317
318 To work around this restriction, consider "hiding" the value behind a reference:
319 either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
320 it around as usual. Example:
321
322 ```
323 #![feature(box_syntax)]
324
325 fn main() {
326     let array: &[isize] = &[1, 2, 3];
327     let _x: Box<&[isize]> = box array; // ok!
328 }
329 ```
330 "##,
331
332 E0396: r##"
333 The value behind a raw pointer can't be determined at compile-time
334 (or even link-time), which means it can't be used in a constant
335 expression. Erroneous code example:
336
337 ```compile_fail,E0396
338 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
339
340 const VALUE: u8 = unsafe { *REG_ADDR };
341 // error: raw pointers cannot be dereferenced in constants
342 ```
343
344 A possible fix is to dereference your pointer at some point in run-time.
345
346 For example:
347
348 ```
349 const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
350
351 let reg_value = unsafe { *REG_ADDR };
352 ```
353 "##,
354
355 E0492: r##"
356 A borrow of a constant containing interior mutability was attempted. Erroneous
357 code example:
358
359 ```compile_fail,E0492
360 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
361
362 const A: AtomicUsize = ATOMIC_USIZE_INIT;
363 static B: &'static AtomicUsize = &A;
364 // error: cannot borrow a constant which may contain interior mutability,
365 //        create a static instead
366 ```
367
368 A `const` represents a constant value that should never change. If one takes
369 a `&` reference to the constant, then one is taking a pointer to some memory
370 location containing the value. Normally this is perfectly fine: most values
371 can't be changed via a shared `&` pointer, but interior mutability would allow
372 it. That is, a constant value could be mutated. On the other hand, a `static` is
373 explicitly a single memory location, which can be mutated at will.
374
375 So, in order to solve this error, either use statics which are `Sync`:
376
377 ```
378 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
379
380 static A: AtomicUsize = ATOMIC_USIZE_INIT;
381 static B: &'static AtomicUsize = &A; // ok!
382 ```
383
384 You can also have this error while using a cell type:
385
386 ```compile_fail,E0492
387 #![feature(const_cell_new)]
388
389 use std::cell::Cell;
390
391 const A: Cell<usize> = Cell::new(1);
392 const B: &'static Cell<usize> = &A;
393 // error: cannot borrow a constant which may contain interior mutability,
394 //        create a static instead
395
396 // or:
397 struct C { a: Cell<usize> }
398
399 const D: C = C { a: Cell::new(1) };
400 const E: &'static Cell<usize> = &D.a; // error
401
402 // or:
403 const F: &'static C = &D; // error
404 ```
405
406 This is because cell types do operations that are not thread-safe. Due to this,
407 they don't implement Sync and thus can't be placed in statics. In this
408 case, `StaticMutex` would work just fine, but it isn't stable yet:
409 https://doc.rust-lang.org/nightly/std/sync/struct.StaticMutex.html
410
411 However, if you still wish to use these types, you can achieve this by an unsafe
412 wrapper:
413
414 ```
415 #![feature(const_cell_new)]
416
417 use std::cell::Cell;
418 use std::marker::Sync;
419
420 struct NotThreadSafe<T> {
421     value: Cell<T>,
422 }
423
424 unsafe impl<T> Sync for NotThreadSafe<T> {}
425
426 static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
427 static B: &'static NotThreadSafe<usize> = &A; // ok!
428 ```
429
430 Remember this solution is unsafe! You will have to ensure that accesses to the
431 cell are synchronized.
432 "##,
433
434 E0494: r##"
435 A reference of an interior static was assigned to another const/static.
436 Erroneous code example:
437
438 ```compile_fail,E0494
439 struct Foo {
440     a: u32
441 }
442
443 static S : Foo = Foo { a : 0 };
444 static A : &'static u32 = &S.a;
445 // error: cannot refer to the interior of another static, use a
446 //        constant instead
447 ```
448
449 The "base" variable has to be a const if you want another static/const variable
450 to refer to one of its fields. Example:
451
452 ```
453 struct Foo {
454     a: u32
455 }
456
457 const S : Foo = Foo { a : 0 };
458 static A : &'static u32 = &S.a; // ok!
459 ```
460 "##,
461
462 E0499: r##"
463 A variable was borrowed as mutable more than once. Erroneous code example:
464
465 ```compile_fail,E0499
466 let mut i = 0;
467 let mut x = &mut i;
468 let mut a = &mut i;
469 // error: cannot borrow `i` as mutable more than once at a time
470 ```
471
472 Please note that in rust, you can either have many immutable references, or one
473 mutable reference. Take a look at
474 https://doc.rust-lang.org/stable/book/references-and-borrowing.html for more
475 information. Example:
476
477
478 ```
479 let mut i = 0;
480 let mut x = &mut i; // ok!
481
482 // or:
483 let mut i = 0;
484 let a = &i; // ok!
485 let b = &i; // still ok!
486 let c = &i; // still ok!
487 ```
488 "##,
489
490 E0500: r##"
491 A borrowed variable was used in another closure. Example of erroneous code:
492
493 ```compile_fail
494 fn you_know_nothing(jon_snow: &mut i32) {
495     let nights_watch = || {
496         *jon_snow = 2;
497     };
498     let starks = || {
499         *jon_snow = 3; // error: closure requires unique access to `jon_snow`
500                        //        but it is already borrowed
501     };
502 }
503 ```
504
505 In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
506 cannot be borrowed by the `starks` closure at the same time. To fix this issue,
507 you can put the closure in its own scope:
508
509 ```
510 fn you_know_nothing(jon_snow: &mut i32) {
511     {
512         let nights_watch = || {
513             *jon_snow = 2;
514         };
515     } // At this point, `jon_snow` is free.
516     let starks = || {
517         *jon_snow = 3;
518     };
519 }
520 ```
521
522 Or, if the type implements the `Clone` trait, you can clone it between
523 closures:
524
525 ```
526 fn you_know_nothing(jon_snow: &mut i32) {
527     let mut jon_copy = jon_snow.clone();
528     let nights_watch = || {
529         jon_copy = 2;
530     };
531     let starks = || {
532         *jon_snow = 3;
533     };
534 }
535 ```
536 "##,
537
538 E0501: r##"
539 This error indicates that a mutable variable is being used while it is still
540 captured by a closure. Because the closure has borrowed the variable, it is not
541 available for use until the closure goes out of scope.
542
543 Note that a capture will either move or borrow a variable, but in this
544 situation, the closure is borrowing the variable. Take a look at
545 http://rustbyexample.com/fn/closures/capture.html for more information about
546 capturing.
547
548 Example of erroneous code:
549
550 ```compile_fail,E0501
551 fn inside_closure(x: &mut i32) {
552     // Actions which require unique access
553 }
554
555 fn outside_closure(x: &mut i32) {
556     // Actions which require unique access
557 }
558
559 fn foo(a: &mut i32) {
560     let bar = || {
561         inside_closure(a)
562     };
563     outside_closure(a); // error: cannot borrow `*a` as mutable because previous
564                         //        closure requires unique access.
565 }
566 ```
567
568 To fix this error, you can place the closure in its own scope:
569
570 ```
571 fn inside_closure(x: &mut i32) {}
572 fn outside_closure(x: &mut i32) {}
573
574 fn foo(a: &mut i32) {
575     {
576         let bar = || {
577             inside_closure(a)
578         };
579     } // borrow on `a` ends.
580     outside_closure(a); // ok!
581 }
582 ```
583
584 Or you can pass the variable as a parameter to the closure:
585
586 ```
587 fn inside_closure(x: &mut i32) {}
588 fn outside_closure(x: &mut i32) {}
589
590 fn foo(a: &mut i32) {
591     let bar = |s: &mut i32| {
592         inside_closure(s)
593     };
594     outside_closure(a);
595     bar(a);
596 }
597 ```
598
599 It may be possible to define the closure later:
600
601 ```
602 fn inside_closure(x: &mut i32) {}
603 fn outside_closure(x: &mut i32) {}
604
605 fn foo(a: &mut i32) {
606     outside_closure(a);
607     let bar = || {
608         inside_closure(a)
609     };
610 }
611 ```
612 "##,
613
614 E0502: r##"
615 This error indicates that you are trying to borrow a variable as mutable when it
616 has already been borrowed as immutable.
617
618 Example of erroneous code:
619
620 ```compile_fail,E0502
621 fn bar(x: &mut i32) {}
622 fn foo(a: &mut i32) {
623     let ref y = a; // a is borrowed as immutable.
624     bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
625             //        as immutable
626 }
627 ```
628
629 To fix this error, ensure that you don't have any other references to the
630 variable before trying to access it mutably:
631
632 ```
633 fn bar(x: &mut i32) {}
634 fn foo(a: &mut i32) {
635     bar(a);
636     let ref y = a; // ok!
637 }
638 ```
639
640 For more information on the rust ownership system, take a look at
641 https://doc.rust-lang.org/stable/book/references-and-borrowing.html.
642 "##,
643
644 E0503: r##"
645 A value was used after it was mutably borrowed.
646
647 Example of erroneous code:
648
649 ```compile_fail,E0503
650 fn main() {
651     let mut value = 3;
652     // Create a mutable borrow of `value`. This borrow
653     // lives until the end of this function.
654     let _borrow = &mut value;
655     let _sum = value + 1; // error: cannot use `value` because
656                           //        it was mutably borrowed
657 }
658 ```
659
660 In this example, `value` is mutably borrowed by `borrow` and cannot be
661 used to calculate `sum`. This is not possible because this would violate
662 Rust's mutability rules.
663
664 You can fix this error by limiting the scope of the borrow:
665
666 ```
667 fn main() {
668     let mut value = 3;
669     // By creating a new block, you can limit the scope
670     // of the reference.
671     {
672         let _borrow = &mut value; // Use `_borrow` inside this block.
673     }
674     // The block has ended and with it the borrow.
675     // You can now use `value` again.
676     let _sum = value + 1;
677 }
678 ```
679
680 Or by cloning `value` before borrowing it:
681
682 ```
683 fn main() {
684     let mut value = 3;
685     // We clone `value`, creating a copy.
686     let value_cloned = value.clone();
687     // The mutable borrow is a reference to `value` and
688     // not to `value_cloned`...
689     let _borrow = &mut value;
690     // ... which means we can still use `value_cloned`,
691     let _sum = value_cloned + 1;
692     // even though the borrow only ends here.
693 }
694 ```
695
696 You can find more information about borrowing in the rust-book:
697 http://doc.rust-lang.org/stable/book/references-and-borrowing.html
698 "##,
699
700 E0504: r##"
701 This error occurs when an attempt is made to move a borrowed variable into a
702 closure.
703
704 Example of erroneous code:
705
706 ```compile_fail,E0504
707 struct FancyNum {
708     num: u8,
709 }
710
711 fn main() {
712     let fancy_num = FancyNum { num: 5 };
713     let fancy_ref = &fancy_num;
714
715     let x = move || {
716         println!("child function: {}", fancy_num.num);
717         // error: cannot move `fancy_num` into closure because it is borrowed
718     };
719
720     x();
721     println!("main function: {}", fancy_ref.num);
722 }
723 ```
724
725 Here, `fancy_num` is borrowed by `fancy_ref` and so cannot be moved into
726 the closure `x`. There is no way to move a value into a closure while it is
727 borrowed, as that would invalidate the borrow.
728
729 If the closure can't outlive the value being moved, try using a reference
730 rather than moving:
731
732 ```
733 struct FancyNum {
734     num: u8,
735 }
736
737 fn main() {
738     let fancy_num = FancyNum { num: 5 };
739     let fancy_ref = &fancy_num;
740
741     let x = move || {
742         // fancy_ref is usable here because it doesn't move `fancy_num`
743         println!("child function: {}", fancy_ref.num);
744     };
745
746     x();
747
748     println!("main function: {}", fancy_num.num);
749 }
750 ```
751
752 If the value has to be borrowed and then moved, try limiting the lifetime of
753 the borrow using a scoped block:
754
755 ```
756 struct FancyNum {
757     num: u8,
758 }
759
760 fn main() {
761     let fancy_num = FancyNum { num: 5 };
762
763     {
764         let fancy_ref = &fancy_num;
765         println!("main function: {}", fancy_ref.num);
766         // `fancy_ref` goes out of scope here
767     }
768
769     let x = move || {
770         // `fancy_num` can be moved now (no more references exist)
771         println!("child function: {}", fancy_num.num);
772     };
773
774     x();
775 }
776 ```
777
778 If the lifetime of a reference isn't enough, such as in the case of threading,
779 consider using an `Arc` to create a reference-counted value:
780
781 ```
782 use std::sync::Arc;
783 use std::thread;
784
785 struct FancyNum {
786     num: u8,
787 }
788
789 fn main() {
790     let fancy_ref1 = Arc::new(FancyNum { num: 5 });
791     let fancy_ref2 = fancy_ref1.clone();
792
793     let x = thread::spawn(move || {
794         // `fancy_ref1` can be moved and has a `'static` lifetime
795         println!("child thread: {}", fancy_ref1.num);
796     });
797
798     x.join().expect("child thread should finish");
799     println!("main thread: {}", fancy_ref2.num);
800 }
801 ```
802 "##,
803
804 E0505: r##"
805 A value was moved out while it was still borrowed.
806
807 Erroneous code example:
808
809 ```compile_fail,E0505
810 struct Value {}
811
812 fn eat(val: Value) {}
813
814 fn main() {
815     let x = Value{};
816     {
817         let _ref_to_val: &Value = &x;
818         eat(x);
819     }
820 }
821 ```
822
823 Here, the function `eat` takes the ownership of `x`. However,
824 `x` cannot be moved because it was borrowed to `_ref_to_val`.
825 To fix that you can do few different things:
826
827 * Try to avoid moving the variable.
828 * Release borrow before move.
829 * Implement the `Copy` trait on the type.
830
831 Examples:
832
833 ```
834 struct Value {}
835
836 fn eat(val: &Value) {}
837
838 fn main() {
839     let x = Value{};
840     {
841         let _ref_to_val: &Value = &x;
842         eat(&x); // pass by reference, if it's possible
843     }
844 }
845 ```
846
847 Or:
848
849 ```
850 struct Value {}
851
852 fn eat(val: Value) {}
853
854 fn main() {
855     let x = Value{};
856     {
857         let _ref_to_val: &Value = &x;
858     }
859     eat(x); // release borrow and then move it.
860 }
861 ```
862
863 Or:
864
865 ```
866 #[derive(Clone, Copy)] // implement Copy trait
867 struct Value {}
868
869 fn eat(val: Value) {}
870
871 fn main() {
872     let x = Value{};
873     {
874         let _ref_to_val: &Value = &x;
875         eat(x); // it will be copied here.
876     }
877 }
878 ```
879
880 You can find more information about borrowing in the rust-book:
881 http://doc.rust-lang.org/stable/book/references-and-borrowing.html
882 "##,
883
884 E0506: r##"
885 This error occurs when an attempt is made to assign to a borrowed value.
886
887 Example of erroneous code:
888
889 ```compile_fail,E0506
890 struct FancyNum {
891     num: u8,
892 }
893
894 fn main() {
895     let mut fancy_num = FancyNum { num: 5 };
896     let fancy_ref = &fancy_num;
897     fancy_num = FancyNum { num: 6 };
898     // error: cannot assign to `fancy_num` because it is borrowed
899
900     println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
901 }
902 ```
903
904 Because `fancy_ref` still holds a reference to `fancy_num`, `fancy_num` can't
905 be assigned to a new value as it would invalidate the reference.
906
907 Alternatively, we can move out of `fancy_num` into a second `fancy_num`:
908
909 ```
910 struct FancyNum {
911     num: u8,
912 }
913
914 fn main() {
915     let mut fancy_num = FancyNum { num: 5 };
916     let moved_num = fancy_num;
917     fancy_num = FancyNum { num: 6 };
918
919     println!("Num: {}, Moved num: {}", fancy_num.num, moved_num.num);
920 }
921 ```
922
923 If the value has to be borrowed, try limiting the lifetime of the borrow using
924 a scoped block:
925
926 ```
927 struct FancyNum {
928     num: u8,
929 }
930
931 fn main() {
932     let mut fancy_num = FancyNum { num: 5 };
933
934     {
935         let fancy_ref = &fancy_num;
936         println!("Ref: {}", fancy_ref.num);
937     }
938
939     // Works because `fancy_ref` is no longer in scope
940     fancy_num = FancyNum { num: 6 };
941     println!("Num: {}", fancy_num.num);
942 }
943 ```
944
945 Or by moving the reference into a function:
946
947 ```
948 struct FancyNum {
949     num: u8,
950 }
951
952 fn main() {
953     let mut fancy_num = FancyNum { num: 5 };
954
955     print_fancy_ref(&fancy_num);
956
957     // Works because function borrow has ended
958     fancy_num = FancyNum { num: 6 };
959     println!("Num: {}", fancy_num.num);
960 }
961
962 fn print_fancy_ref(fancy_ref: &FancyNum){
963     println!("Ref: {}", fancy_ref.num);
964 }
965 ```
966 "##,
967
968 }
969
970 register_diagnostics! {
971     E0493, // destructors cannot be evaluated at compile-time
972     E0524, // two closures require unique access to `..` at the same time
973     E0526, // shuffle indices are not constant
974     E0625, // thread-local statics cannot be accessed at compile-time
975 }