diff options
| author | est31 <MTest31@outlook.com> | 2017-11-19 23:35:53 +0100 |
|---|---|---|
| committer | est31 <MTest31@outlook.com> | 2017-11-26 16:36:52 +0100 |
| commit | c9af68e90cc7a551130873363a6776a4c04e2a6d (patch) | |
| tree | 7cacceb88af3e9ae5012ccb89d7eea3e09896809 | |
| parent | 2ca00a948934766950167e997903a2cc0243c5cf (diff) | |
| download | rust-c9af68e90cc7a551130873363a6776a4c04e2a6d.tar.gz rust-c9af68e90cc7a551130873363a6776a4c04e2a6d.zip | |
Replace -Zborrowck-mir with -Zborrowck=mode
where mode is one of {ast,mir,compare}.
This commit only implements the functionality.
The tests will be updated in a follow up commit.
| -rw-r--r-- | src/librustc/session/config.rs | 44 | ||||
| -rw-r--r-- | src/librustc/session/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_borrowck/borrowck/mod.rs | 11 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/util/borrowck_errors.rs | 154 |
5 files changed, 160 insertions, 53 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a56f850942c..97b9d776a57 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -362,6 +362,9 @@ top_level_options!( debugging_opts: DebuggingOptions [TRACKED], prints: Vec<PrintRequest> [UNTRACKED], + // Determines which borrow checker(s) to run. This is the parsed, sanitized + // version of `debugging_opts.borrowck`, which is just a plain string. + borrowck_mode: BorrowckMode [UNTRACKED], cg: CodegenOptions [TRACKED], // FIXME(mw): We track this for now but it actually doesn't make too // much sense: The value of this option can stay the same @@ -401,6 +404,32 @@ pub enum PrintRequest { NativeStaticLibs, } +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum BorrowckMode { + Ast, + Mir, + Compare, +} + +impl BorrowckMode { + /// Should we emit the AST-based borrow checker errors? + pub fn use_ast(self) -> bool { + match self { + BorrowckMode::Ast => true, + BorrowckMode::Compare => true, + BorrowckMode::Mir => false, + } + } + /// Should we emit the MIR-based borrow checker errors? + pub fn use_mir(self) -> bool { + match self { + BorrowckMode::Ast => false, + BorrowckMode::Compare => true, + BorrowckMode::Mir => true, + } + } +} + pub enum Input { /// Load source from file File(PathBuf), @@ -526,6 +555,7 @@ pub fn basic_options() -> Options { incremental: None, debugging_opts: basic_debugging_options(), prints: Vec::new(), + borrowck_mode: BorrowckMode::Ast, cg: basic_codegen_options(), error_format: ErrorOutputType::default(), externs: Externs(BTreeMap::new()), @@ -973,8 +1003,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "make unnamed regions display as '# (where # is some non-ident unique id)"), emit_end_regions: bool = (false, parse_bool, [UNTRACKED], "emit EndRegion as part of MIR; enable transforms that solely process EndRegion"), - borrowck_mir: bool = (false, parse_bool, [UNTRACKED], - "implicitly treat functions as if they have `#[rustc_mir_borrowck]` attribute"), + borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED], + "select which borrowck is used (`ast`, `mir`, or `compare`)"), time_passes: bool = (false, parse_bool, [UNTRACKED], "measure time of each rustc pass"), count_llvm_insns: bool = (false, parse_bool, @@ -1743,6 +1773,15 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } })); + let borrowck_mode = match debugging_opts.borrowck.as_ref().map(|s| &s[..]) { + None | Some("ast") => BorrowckMode::Ast, + Some("mir") => BorrowckMode::Mir, + Some("compare") => BorrowckMode::Compare, + Some(m) => { + early_error(error_format, &format!("unknown borrowchk mode `{}`", m)) + }, + }; + if !cg.remark.is_empty() && debuginfo == NoDebugInfo { early_warn(error_format, "-C remark will not show source locations without \ --debuginfo"); @@ -1784,6 +1823,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) incremental, debugging_opts, prints, + borrowck_mode, cg, error_format, externs: Externs(externs), diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 642153c08f6..227efcf4d6e 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -416,7 +416,7 @@ impl Session { pub fn emit_end_regions(&self) -> bool { self.opts.debugging_opts.emit_end_regions || (self.opts.debugging_opts.mir_emit_validate > 0) || - self.opts.debugging_opts.borrowck_mir + self.opts.borrowck_mode.use_mir() } pub fn lto(&self) -> bool { self.opts.cg.lto || self.target.target.options.requires_lto diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 36b397bbbe5..40837c5e8d6 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -269,6 +269,17 @@ impl<'b, 'tcx: 'b> BorrowckErrors for BorrowckCtxt<'b, 'tcx> { { self.tcx.sess.struct_span_err(sp, msg) } + + fn cancel_if_wrong_origin<'a>(&'a self, + mut diag: DiagnosticBuilder<'a>, + o: Origin) + -> DiagnosticBuilder<'a> + { + if !o.should_emit_errors(self.tcx.sess.opts.borrowck_mode) { + self.tcx.sess.diagnostic().cancel(&mut diag); + } + diag + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs index 4d54c6f473c..289636be321 100644 --- a/src/librustc_mir/borrow_check.rs +++ b/src/librustc_mir/borrow_check.rs @@ -54,7 +54,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { if { !tcx.has_attr(def_id, "rustc_mir_borrowck") && - !tcx.sess.opts.debugging_opts.borrowck_mir && + !tcx.sess.opts.borrowck_mode.use_mir() && !tcx.sess.opts.debugging_opts.nll } { return; diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 2f29b79eeb6..00248400c55 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -9,6 +9,7 @@ // except according to those terms. use rustc::ty::{self, TyCtxt}; +use rustc::session::config::BorrowckMode; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use syntax_pos::{MultiSpan, Span}; @@ -19,20 +20,34 @@ pub enum Origin { Ast, Mir } impl fmt::Display for Origin { fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { - match *self { - Origin::Mir => write!(w, " (Mir)"), - Origin::Ast => ty::tls::with_opt(|opt_tcx| { - // If user passed `-Z borrowck-mir`, then include an - // AST origin as part of the error report - if let Some(tcx) = opt_tcx { - if tcx.sess.opts.debugging_opts.borrowck_mir { - return write!(w, " (Ast)"); - } - } - // otherwise, do not include the origin (i.e., print - // nothing at all) - Ok(()) - }), + // If the user passed `-Z borrowck=compare`, then include + // origin info as part of the error report, + // otherwise + let display_origin = ty::tls::with_opt(|opt_tcx| { + if let Some(tcx) = opt_tcx { + tcx.sess.opts.borrowck_mode == BorrowckMode::Compare + } else { + false + } + }); + if display_origin { + match *self { + Origin::Mir => write!(w, " (Mir)"), + Origin::Ast => write!(w, " (Ast)"), + } + } else { + // Print no origin info + Ok(()) + } + } +} + +impl Origin { + /// Whether we should emit errors for the origin in the given mode + pub fn should_emit_errors(self, mode: BorrowckMode) -> bool { + match self { + Origin::Ast => mode.use_ast(), + Origin::Mir => mode.use_mir(), } } } @@ -49,12 +64,23 @@ pub trait BorrowckErrors { msg: &str) -> DiagnosticBuilder<'a>; + /// Cancels the given error if we shouldn't emit errors for a given + /// origin in the current mode. + /// + /// Always make sure that the error gets passed through this function + /// before you return it. + fn cancel_if_wrong_origin<'a>(&'a self, + diag: DiagnosticBuilder<'a>, + o: Origin) + -> DiagnosticBuilder<'a>; + fn cannot_move_when_borrowed(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder { - struct_span_err!(self, span, E0505, - "cannot move out of `{}` because it is borrowed{OGN}", - desc, OGN=o) + let err = struct_span_err!(self, span, E0505, + "cannot move out of `{}` because it is borrowed{OGN}", + desc, OGN=o); + self.cancel_if_wrong_origin(err, o) } fn cannot_use_when_mutably_borrowed(&self, @@ -72,7 +98,7 @@ pub trait BorrowckErrors { err.span_label(borrow_span, format!("borrow of `{}` occurs here", borrow_desc)); err.span_label(span, format!("use of borrowed `{}`", borrow_desc)); - err + self.cancel_if_wrong_origin(err, o) } fn cannot_act_on_uninitialized_variable(&self, @@ -82,9 +108,10 @@ pub trait BorrowckErrors { o: Origin) -> DiagnosticBuilder { - struct_span_err!(self, span, E0381, - "{} of possibly uninitialized variable: `{}`{OGN}", - verb, desc, OGN=o) + let err = struct_span_err!(self, span, E0381, + "{} of possibly uninitialized variable: `{}`{OGN}", + verb, desc, OGN=o); + self.cancel_if_wrong_origin(err, o) } fn cannot_mutably_borrow_multiply(&self, @@ -118,7 +145,7 @@ pub trait BorrowckErrors { err.span_label(old_load_end_span, "first borrow ends here"); } } - err + self.cancel_if_wrong_origin(err, o) } fn cannot_uniquely_borrow_by_two_closures(&self, @@ -143,7 +170,7 @@ pub trait BorrowckErrors { old_load_end_span, "borrow from first closure ends here"); } - err + self.cancel_if_wrong_origin(err, o) } fn cannot_uniquely_borrow_by_one_closure(&self, @@ -167,7 +194,7 @@ pub trait BorrowckErrors { if let Some(previous_end_span) = previous_end_span { err.span_label(previous_end_span, "borrow ends here"); } - err + self.cancel_if_wrong_origin(err, o) } fn cannot_reborrow_already_uniquely_borrowed(&self, @@ -192,7 +219,7 @@ pub trait BorrowckErrors { if let Some(previous_end_span) = previous_end_span { err.span_label(previous_end_span, "borrow from closure ends here"); } - err + self.cancel_if_wrong_origin(err, o) } fn cannot_reborrow_already_borrowed(&self, @@ -216,7 +243,7 @@ pub trait BorrowckErrors { if let Some(old_load_end_span) = old_load_end_span { err.span_label(old_load_end_span, format!("{} borrow ends here", kind_old)); } - err + self.cancel_if_wrong_origin(err, o) } fn cannot_assign_to_borrowed(&self, span: Span, borrow_span: Span, desc: &str, o: Origin) @@ -229,30 +256,35 @@ pub trait BorrowckErrors { err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc)); err.span_label(span, format!("assignment to borrowed `{}` occurs here", desc)); - err + self.cancel_if_wrong_origin(err, o) } fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder { - struct_span_err!(self, span, E0504, - "cannot move `{}` into closure because it is borrowed{OGN}", - desc, OGN=o) + let err = struct_span_err!(self, span, E0504, + "cannot move `{}` into closure because it is borrowed{OGN}", + desc, OGN=o); + + self.cancel_if_wrong_origin(err, o) } fn cannot_reassign_immutable(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder { - struct_span_err!(self, span, E0384, - "cannot assign twice to immutable variable `{}`{OGN}", - desc, OGN=o) + let err = struct_span_err!(self, span, E0384, + "cannot assign twice to immutable variable `{}`{OGN}", + desc, OGN=o); + + self.cancel_if_wrong_origin(err, o) } fn cannot_assign(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder { - struct_span_err!(self, span, E0594, - "cannot assign to {}{OGN}", - desc, OGN=o) + let err = struct_span_err!(self, span, E0594, + "cannot assign to {}{OGN}", + desc, OGN=o); + self.cancel_if_wrong_origin(err, o) } fn cannot_assign_static(&self, span: Span, desc: &str, o: Origin) @@ -270,7 +302,8 @@ pub trait BorrowckErrors { err.span_label( move_from_span, format!("cannot move out of {}", move_from_desc)); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_move_out_of_interior_noncopy(&self, @@ -290,7 +323,8 @@ pub trait BorrowckErrors { a non-copy {}{OGN}", ty, type_name, OGN=o); err.span_label(move_from_span, "cannot move out of here"); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_move_out_of_interior_of_drop(&self, @@ -304,7 +338,8 @@ pub trait BorrowckErrors { which implements the `Drop` trait{OGN}", container_ty, OGN=o); err.span_label(move_from_span, "cannot move out of here"); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_act_on_moved_value(&self, @@ -318,7 +353,8 @@ pub trait BorrowckErrors { let err = struct_span_err!(self, use_span, E0382, "{} of {}moved value: `{}`{OGN}", verb, optional_adverb_for_moved, moved_path, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_partially_reinit_an_uninit_struct(&self, @@ -332,7 +368,8 @@ pub trait BorrowckErrors { E0383, "partial reinitialization of uninitialized structure `{}`{OGN}", uninit_path, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn closure_cannot_assign_to_borrowed(&self, @@ -343,7 +380,8 @@ pub trait BorrowckErrors { { let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}", descr, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_borrow_path_as_mutable(&self, @@ -354,7 +392,8 @@ pub trait BorrowckErrors { { let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}", path, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_borrow_across_generator_yield(&self, @@ -369,7 +408,8 @@ pub trait BorrowckErrors { "borrow may still be in use when generator yields{OGN}", OGN=o); err.span_label(yield_span, "possible yield occurs here"); - err + + self.cancel_if_wrong_origin(err, o) } fn path_does_not_live_long_enough(&self, @@ -380,7 +420,8 @@ pub trait BorrowckErrors { { let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}", path, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn lifetime_too_short_for_reborrow(&self, @@ -393,7 +434,8 @@ pub trait BorrowckErrors { "lifetime of {} is too short to guarantee \ its contents can be safely reborrowed{OGN}", path, OGN=o); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_act_on_capture_in_sharable_fn(&self, @@ -408,7 +450,8 @@ pub trait BorrowckErrors { "{} in a captured outer variable in an `Fn` closure{OGN}", bad_thing, OGN=o); err.span_help(help_span, help_msg); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_assign_into_immutable_reference(&self, @@ -420,7 +463,8 @@ pub trait BorrowckErrors { let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}", bad_thing, OGN=o); err.span_label(span, "assignment into an immutable reference"); - err + + self.cancel_if_wrong_origin(err, o) } fn cannot_capture_in_long_lived_closure(&self, @@ -437,7 +481,8 @@ pub trait BorrowckErrors { borrowed_path, OGN=o); err.span_label(capture_span, format!("{} is borrowed here", borrowed_path)) .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path)); - err + + self.cancel_if_wrong_origin(err, o) } } @@ -458,4 +503,15 @@ impl<'b, 'gcx, 'tcx> BorrowckErrors for TyCtxt<'b, 'gcx, 'tcx> { { self.sess.struct_span_err(sp, msg) } + + fn cancel_if_wrong_origin<'a>(&'a self, + mut diag: DiagnosticBuilder<'a>, + o: Origin) + -> DiagnosticBuilder<'a> + { + if !o.should_emit_errors(self.sess.opts.borrowck_mode) { + self.sess.diagnostic().cancel(&mut diag); + } + diag + } } |
