diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 94dc8e2901577..98568f860a4fd 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -74,6 +74,7 @@ use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; use syntax::codemap::MultiSpan; +use syntax::edition::Edition; use syntax::feature_gate; use syntax::symbol::{Symbol, keywords, InternedString}; use syntax_pos::Span; @@ -1403,34 +1404,51 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// What mode(s) of borrowck should we run? AST? MIR? both? /// (Also considers the `#![feature(nll)]` setting.) pub fn borrowck_mode(&self) -> BorrowckMode { + // Here are the main constraints we need to deal with: + // + // 1. An opts.borrowck_mode of `BorrowckMode::Ast` is + // synonymous with no `-Z borrowck=...` flag at all. + // (This is arguably a historical accident.) + // + // 2. `BorrowckMode::Migrate` is the limited migration to + // NLL that we are deploying with the 2018 edition. + // + // 3. We want to allow developers on the Nightly channel + // to opt back into the "hard error" mode for NLL, + // (which they can do via specifying `#![feature(nll)]` + // explicitly in their crate). + // + // So, this precedence list is how pnkfelix chose to work with + // the above constraints: + // + // * `#![feature(nll)]` *always* means use NLL with hard + // errors. (To simplify the code here, it now even overrides + // a user's attempt to specify `-Z borrowck=compare`, which + // we arguably do not need anymore and should remove.) + // + // * Otherwise, if no `-Z borrowck=...` flag was given (or + // if `borrowck=ast` was specified), then use the default + // as required by the edition. + // + // * Otherwise, use the behavior requested via `-Z borrowck=...` + + if self.features().nll { return BorrowckMode::Mir; } + match self.sess.opts.borrowck_mode { mode @ BorrowckMode::Mir | - mode @ BorrowckMode::Compare => mode, - - // `BorrowckMode::Ast` is synonymous with no `-Z - // borrowck=...` flag at all. Therefore, we definitely - // want `#![feature(nll)]` to override it. - mode @ BorrowckMode::Ast => { - if self.features().nll { - BorrowckMode::Mir - } else { - mode - } - } - - // `BorrowckMode::Migrate` is modelling the behavior one - // will eventually specify via `--edition 2018`. We want - // to allow developers on the Nightly channel to opt back - // into the "hard error" mode for NLL, which they can do - // via specifying `#![feature(nll)]` explicitly in their - // crate. - mode @ BorrowckMode::Migrate => { - if self.features().nll { - BorrowckMode::Mir - } else { - mode - } - } + mode @ BorrowckMode::Compare | + mode @ BorrowckMode::Migrate => mode, + + BorrowckMode::Ast => match self.sess.edition() { + Edition::Edition2015 => BorrowckMode::Ast, + Edition::Edition2018 => BorrowckMode::Migrate, + + // For now, future editions mean Migrate. (But it + // would make a lot of sense for it to be changed to + // `BorrowckMode::Mir`, depending on how we plan to + // time the forcing of full migration to NLL.) + _ => BorrowckMode::Migrate, + }, } } diff --git a/src/test/ui/generator/generator-with-nll.rs b/src/test/ui/generator/generator-with-nll.rs index 3223ff4dc8b59..fdfe9e2c562e0 100644 --- a/src/test/ui/generator/generator-with-nll.rs +++ b/src/test/ui/generator/generator-with-nll.rs @@ -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); }; diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr index 7e39d3c545903..1dc663d8bcbf7 100644 --- a/src/test/ui/generator/generator-with-nll.stderr +++ b/src/test/ui/generator/generator-with-nll.stderr @@ -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`.