"##,
E0383: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
This error occurs when an attempt is made to partially reinitialize a
structure that is currently uninitialized.
For example, this can happen when a drop has taken place:
-```compile_fail,E0383
+```compile_fail
struct Foo {
a: u32,
}
"##,*/
E0387: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below:
-```compile_fail,E0387
+```compile_fail
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }
"##,
E0389: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
An attempt was made to mutate data using a non-mutable reference. This
commonly occurs when attempting to assign to a non-mutable reference of a
mutable reference (`&(&mut T)`).
Example of erroneous code:
-```compile_fail,E0389
+```compile_fail
struct FancyNum {
num: u8,
}
let mut i = 0;
let mut x = &mut i;
let mut a = &mut i;
+x;
// error: cannot borrow `i` as mutable more than once at a time
```
let a = &i; // ok!
let b = &i; // still ok!
let c = &i; // still ok!
+b;
+a;
```
"##,
E0500: r##"
-A borrowed variable was used in another closure. Example of erroneous code:
+A borrowed variable was used by a closure. Example of erroneous code:
-```compile_fail
+```compile_fail,E0500
fn you_know_nothing(jon_snow: &mut i32) {
- let nights_watch = || {
- *jon_snow = 2;
- };
+ let nights_watch = &jon_snow;
let starks = || {
*jon_snow = 3; // error: closure requires unique access to `jon_snow`
// but it is already borrowed
};
+ println!("{}", nights_watch);
}
```
-In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
+In here, `jon_snow` is already borrowed by the `nights_watch` reference, so it
cannot be borrowed by the `starks` closure at the same time. To fix this issue,
-you can put the closure in its own scope:
+you can create the closure after the borrow has ended:
```
fn you_know_nothing(jon_snow: &mut i32) {
- {
- let nights_watch = || {
- *jon_snow = 2;
- };
- } // At this point, `jon_snow` is free.
+ let nights_watch = &jon_snow;
+ println!("{}", nights_watch);
let starks = || {
*jon_snow = 3;
};
```
fn you_know_nothing(jon_snow: &mut i32) {
let mut jon_copy = jon_snow.clone();
- let nights_watch = || {
- jon_copy = 2;
- };
let starks = || {
*jon_snow = 3;
};
+ println!("{}", jon_copy);
}
```
"##,
}
fn foo(a: &mut i32) {
- let bar = || {
+ let mut bar = || {
inside_closure(a)
};
outside_closure(a); // error: cannot borrow `*a` as mutable because previous
// closure requires unique access.
+ bar();
}
```
-To fix this error, you can place the closure in its own scope:
+To fix this error, you can finish using the closure before using the captured
+variable:
```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
- {
- let bar = || {
- inside_closure(a)
- };
- } // borrow on `a` ends.
+ let mut bar = || {
+ inside_closure(a)
+ };
+ bar();
+ // borrow on `a` ends.
outside_closure(a); // ok!
}
```
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
- let bar = |s: &mut i32| {
+ let mut bar = |s: &mut i32| {
inside_closure(s)
};
outside_closure(a);
fn foo(a: &mut i32) {
outside_closure(a);
- let bar = || {
+ let mut bar = || {
inside_closure(a)
};
+ bar();
}
```
"##,
let ref y = a; // a is borrowed as immutable.
bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
// as immutable
+ println!("{}", y);
}
```
fn foo(a: &mut i32) {
bar(a);
let ref y = a; // ok!
+ println!("{}", y);
}
```
```compile_fail,E0503
fn main() {
let mut value = 3;
- // Create a mutable borrow of `value`. This borrow
- // lives until the end of this function.
- let _borrow = &mut value;
+ // Create a mutable borrow of `value`.
+ let borrow = &mut value;
let _sum = value + 1; // error: cannot use `value` because
// it was mutably borrowed
+ println!("{}", borrow);
}
```
used to calculate `sum`. This is not possible because this would violate
Rust's mutability rules.
-You can fix this error by limiting the scope of the borrow:
+You can fix this error by finishing using the borrow before the next use of
+the value:
```
fn main() {
let mut value = 3;
- // By creating a new block, you can limit the scope
- // of the reference.
- {
- let _borrow = &mut value; // Use `_borrow` inside this block.
- }
+ let borrow = &mut value;
+ println!("{}", borrow);
// The block has ended and with it the borrow.
// You can now use `value` again.
let _sum = value + 1;
let value_cloned = value.clone();
// The mutable borrow is a reference to `value` and
// not to `value_cloned`...
- let _borrow = &mut value;
+ let borrow = &mut value;
// ... which means we can still use `value_cloned`,
let _sum = value_cloned + 1;
// even though the borrow only ends here.
+ println!("{}", borrow);
}
```
"##,
E0504: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
This error occurs when an attempt is made to move a borrowed variable into a
closure.
Example of erroneous code:
-```compile_fail,E0504
+```compile_fail
struct FancyNum {
num: u8,
}
fn main() {
let x = Value{};
- let _ref_to_val: &Value = &x;
+
+ let ref_to_val: &Value = &x;
eat(&x); // pass by reference, if it's possible
- borrow(_ref_to_val);
+ borrow(ref_to_val);
}
```
fn main() {
let x = Value{};
- {
- let _ref_to_val: &Value = &x;
- borrow(_ref_to_val);
- }
- eat(x); // release borrow and then move it.
+
+ let ref_to_val: &Value = &x;
+ borrow(ref_to_val);
+ // ref_to_val is no longer used.
+ eat(x);
}
```
fn main() {
let x = Value{};
- let _ref_to_val: &Value = &x;
+ let ref_to_val: &Value = &x;
eat(x); // it will be copied here.
- borrow(_ref_to_val);
+ borrow(ref_to_val);
}
```
"##,
E0595: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
Closures cannot mutate immutable captured variables.
Erroneous code example:
-```compile_fail,E0595
+```compile_fail,E0594
let x = 3; // error: closure cannot assign to immutable local variable `x`
let mut c = || { x += 1 };
```
"##,
E0597: r##"
-This error occurs because a borrow was made inside a variable which has a
-greater lifetime than the borrowed one.
+This error occurs because a value was dropped while it was still borrowed
Example of erroneous code:
}
let mut x = Foo { x: None };
-let y = 0;
-x.x = Some(&y); // error: `y` does not live long enough
+{
+ let y = 0;
+ x.x = Some(&y); // error: `y` does not live long enough
+}
+println!("{:?}", x.x);
```
-In here, `x` is created before `y` and therefore has a greater lifetime. Always
-keep in mind that values in a scope are dropped in the opposite order they are
-created. So to fix the previous example, just make the `y` lifetime greater than
-the `x`'s one:
+In here, `y` is dropped at the end of the inner scope, but it is borrowed by
+`x` until the `println`. To fix the previous example, just remove the scope
+so that `y` isn't dropped until after the println
```
struct Foo<'a> {
x: Option<&'a u32>,
}
-let y = 0;
let mut x = Foo { x: None };
+
+let y = 0;
x.x = Some(&y);
+
+println!("{:?}", x.x);
```
"##,
```
"##,
+E0729: r##"
+Support for Non-Lexical Lifetimes (NLL) has been included in the Rust compiler
+since 1.31, and has been enabled on the 2015 edition since 1.36. The new borrow
+checker for NLL uncovered some bugs in the old borrow checker, which in some
+cases allowed unsound code to compile, resulting in memory safety issues.
+
+### What do I do?
+
+Change your code so the warning does no longer trigger. For backwards
+compatibility, this unsound code may still compile (with a warning) right now.
+However, at some point in the future, the compiler will no longer accept this
+code and will throw a hard error.
+
+### Shouldn't you fix the old borrow checker?
+
+The old borrow checker has known soundness issues that are basically impossible
+to fix. The new NLL-based borrow checker is the fix.
+
+### Can I turn these warnings into errors by denying a lint?
+
+No.
+
+### When are these warnings going to turn into errors?
+
+No formal timeline for turning the warnings into errors has been set. See
+[GitHub issue 58781](https://github.com/rust-lang/rust/issues/58781) for more
+information.
+
+### Why do I get this message with code that doesn't involve borrowing?
+
+There are some known bugs that trigger this message.
+"##,
}
register_diagnostics! {