Auto merge of #52681 - pnkfelix:z-borrowck-migrate, r=nikomatsakis

Add `-Z borrowck=migrate`

This adds `-Z borrowck=migrate`, which represents the way we want to migrate to NLL under Rust versions to come. It also hooks this new mode into `--edition 2018`, which means we're officially turning NLL on in the 2018 edition.

The basic idea of `-Z borrowck=migrate` that there are cases where NLL is fixing old soundness bugs in the borrow-checker, but in order to avoid just breaking code by immediately rejecting the programs that hit those soundness bugs, we instead use the following strategy:

If your code is accepted by NLL, then we accept it.
If your code is rejected by both NLL and the old AST-borrowck, then we reject it.
If your code is rejected by NLL but accepted by the old AST-borrowck, then we emit the new NLL errors as **warnings**.

These warnings will be turned into hard errors in the future, and they say so in these diagnostics.

Fix #46908
This commit is contained in:
bors 2018-07-27 09:10:07 +00:00
commit b18b9edf00
20 changed files with 380 additions and 80 deletions

View file

@ -0,0 +1,9 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View file

@ -0,0 +1,40 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This is a test that the `#![feature(nll)]` opt-in overrides the
// migration mode. The intention here is to emulate the goal behavior
// that `--edition 2018` effects on borrowck (modeled here by `-Z
// borrowck=migrate`) are themselves overridden by the
// `#![feature(nll)]` opt-in.
//
// Therefore, for developer convenience, under `#[feature(nll)]` the
// NLL checks will be emitted as errors *even* in the presence of `-Z
// borrowck=migrate`.
// revisions: zflag edition
// [zflag]compile-flags: -Z borrowck=migrate
// [edition]compile-flags: --edition 2018
#![feature(nll)]
fn main() {
match Some(&4) {
None => {},
ref mut foo
if {
(|| { let bar = foo; bar.take() })();
//[zflag]~^ ERROR cannot move out of borrowed content [E0507]
//[edition]~^^ ERROR cannot move out of borrowed content [E0507]
false
} => {},
Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
_ => println!("Here is some supposedly unreachable code."),
}
}

View file

@ -0,0 +1,9 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View file

@ -0,0 +1,24 @@
warning[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-migrate-to-nll.rs:35:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
|
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
--> $DIR/borrowck-migrate-to-nll.rs:35:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| cannot move out of `foo`, as it is immutable for the pattern guard
| cannot move
|
= note: variables bound in patterns are immutable until the end of the pattern guard
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
It represents potential unsoundness in your code.
This warning will become a hard error in the future.

View file

@ -0,0 +1,41 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This is a test of the borrowck migrate mode. It leverages #27282, a
// bug that is fixed by NLL: this code is (unsoundly) accepted by
// AST-borrowck, but is correctly rejected by the NLL borrowck.
//
// Therefore, for backwards-compatiblity, under borrowck=migrate the
// NLL checks will be emitted as *warnings*.
// NLL mode makes this compile-fail; we cannot currently encode a
// test that is run-pass or compile-fail based on compare-mode. So
// just ignore it instead:
// ignore-compare-mode-nll
// revisions: zflag edition
//[zflag]compile-flags: -Z borrowck=migrate
//[edition]compile-flags: --edition 2018
//[zflag] run-pass
//[edition] run-pass
fn main() {
match Some(&4) {
None => {},
ref mut foo
if {
(|| { let bar = foo; bar.take() })();
false
} => {},
Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
_ => println!("Here is some supposedly unreachable code."),
}
}

View file

@ -0,0 +1,24 @@
warning[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-migrate-to-nll.rs:35:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
|
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
It represents potential unsoundness in your code.
This warning will become a hard error in the future.
warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
--> $DIR/borrowck-migrate-to-nll.rs:35:17
|
LL | (|| { let bar = foo; bar.take() })();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| cannot move out of `foo`, as it is immutable for the pattern guard
| cannot move
|
= note: variables bound in patterns are immutable until the end of the pattern guard
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
It represents potential unsoundness in your code.
This warning will become a hard error in the future.

View file

@ -8,17 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: -Z borrowck=compare
#![feature(generators)]
#![feature(nll)]
fn main() {
|| {
// The reference in `_a` is a Legal with NLL since it ends before the yield
let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
//~^ borrow may still be in use when generator yields (Mir)
let _a = &mut true;
let b = &mut true;
//~^ borrow may still be in use when generator yields
yield ();
println!("{}", b);
};

View file

@ -1,30 +1,12 @@
error[E0626]: borrow may still be in use when generator yields (Ast)
--> $DIR/generator-with-nll.rs:19:23
error[E0626]: borrow may still be in use when generator yields
--> $DIR/generator-with-nll.rs:18:17
|
LL | let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
| ^^^^
...
LL | yield ();
| -------- possible yield occurs here
error[E0626]: borrow may still be in use when generator yields (Ast)
--> $DIR/generator-with-nll.rs:20:22
|
LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
| ^^^^
LL | //~^ borrow may still be in use when generator yields (Mir)
LL | yield ();
| -------- possible yield occurs here
error[E0626]: borrow may still be in use when generator yields (Mir)
--> $DIR/generator-with-nll.rs:20:17
|
LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
LL | let b = &mut true;
| ^^^^^^^^^
LL | //~^ borrow may still be in use when generator yields (Mir)
LL | //~^ borrow may still be in use when generator yields
LL | yield ();
| -------- possible yield occurs here
error: aborting due to 3 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0626`.