Add flag indicating whether AST borrowck query signalled any error.

This commit is contained in:
Felix S. Klock II 2018-07-20 16:38:00 +02:00
parent fefe81605d
commit 655894baf9
4 changed files with 44 additions and 4 deletions

View File

@ -15,9 +15,15 @@ use util::nodemap::FxHashSet;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult}; StableHasherResult};
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum SignalledError { SawSomeError, NoErrorsSeen }
impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen });
#[derive(Debug, RustcEncodable, RustcDecodable)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BorrowCheckResult { pub struct BorrowCheckResult {
pub used_mut_nodes: FxHashSet<HirId>, pub used_mut_nodes: FxHashSet<HirId>,
pub signalled_any_error: SignalledError,
} }
impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult { impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult {
@ -26,7 +32,9 @@ impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult {
hasher: &mut StableHasher<W>) { hasher: &mut StableHasher<W>) {
let BorrowCheckResult { let BorrowCheckResult {
ref used_mut_nodes, ref used_mut_nodes,
ref signalled_any_error,
} = *self; } = *self;
used_mut_nodes.hash_stable(hcx, hasher); used_mut_nodes.hash_stable(hcx, hasher);
signalled_any_error.hash_stable(hcx, hasher);
} }
} }

View File

@ -447,10 +447,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
.region_scope_tree .region_scope_tree
.yield_in_scope_for_expr(scope, .yield_in_scope_for_expr(scope,
cmt.hir_id, cmt.hir_id,
self.bccx.body) { self.bccx.body)
{
self.bccx.cannot_borrow_across_generator_yield(borrow_span, self.bccx.cannot_borrow_across_generator_yield(borrow_span,
yield_span, yield_span,
Origin::Ast).emit(); Origin::Ast).emit();
self.bccx.signal_error();
} }
} }
@ -507,9 +509,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
new_loan, old_loan, old_loan, new_loan).err(); new_loan, old_loan, old_loan, new_loan).err();
match (err_old_new, err_new_old) { match (err_old_new, err_new_old) {
(Some(mut err), None) | (None, Some(mut err)) => err.emit(), (Some(mut err), None) | (None, Some(mut err)) => {
err.emit();
self.bccx.signal_error();
}
(Some(mut err_old), Some(mut err_new)) => { (Some(mut err_old), Some(mut err_new)) => {
err_old.emit(); err_old.emit();
self.bccx.signal_error();
err_new.cancel(); err_new.cancel();
} }
(None, None) => return true, (None, None) => return true,
@ -695,6 +701,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
loan_span, &self.bccx.loan_path_to_string(&loan_path), loan_span, &self.bccx.loan_path_to_string(&loan_path),
Origin::Ast) Origin::Ast)
.emit(); .emit();
self.bccx.signal_error();
} }
} }
} }
@ -745,6 +752,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
}; };
err.emit(); err.emit();
self.bccx.signal_error();
} }
} }
} }
@ -914,5 +922,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
self.bccx.cannot_assign_to_borrowed( self.bccx.cannot_assign_to_borrowed(
span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast) span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast)
.emit(); .emit();
self.bccx.signal_error();
} }
} }

View File

@ -99,6 +99,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<Move
"captured outer variable"); "captured outer variable");
} }
err.emit(); err.emit();
bccx.signal_error();
} }
} }

View File

@ -28,7 +28,7 @@ use rustc::middle::dataflow::DataFlowContext;
use rustc::middle::dataflow::BitwiseOperator; use rustc::middle::dataflow::BitwiseOperator;
use rustc::middle::dataflow::DataFlowOperator; use rustc::middle::dataflow::DataFlowOperator;
use rustc::middle::dataflow::KillFrom; use rustc::middle::dataflow::KillFrom;
use rustc::middle::borrowck::BorrowCheckResult; use rustc::middle::borrowck::{BorrowCheckResult, SignalledError};
use rustc::hir::def_id::{DefId, LocalDefId}; use rustc::hir::def_id::{DefId, LocalDefId};
use rustc::middle::expr_use_visitor as euv; use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization as mc;
@ -42,7 +42,7 @@ use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
use rustc_mir::util::suggest_ref_mut; use rustc_mir::util::suggest_ref_mut;
use rustc::util::nodemap::FxHashSet; use rustc::util::nodemap::FxHashSet;
use std::cell::RefCell; use std::cell::{Cell, RefCell};
use std::fmt; use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -105,6 +105,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
// and do not need borrowchecking. // and do not need borrowchecking.
return Lrc::new(BorrowCheckResult { return Lrc::new(BorrowCheckResult {
used_mut_nodes: FxHashSet(), used_mut_nodes: FxHashSet(),
signalled_any_error: SignalledError::NoErrorsSeen,
}) })
} }
_ => { } _ => { }
@ -121,6 +122,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
owner_def_id, owner_def_id,
body, body,
used_mut_nodes: RefCell::new(FxHashSet()), used_mut_nodes: RefCell::new(FxHashSet()),
signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
}; };
// Eventually, borrowck will always read the MIR, but at the // Eventually, borrowck will always read the MIR, but at the
@ -154,6 +156,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
Lrc::new(BorrowCheckResult { Lrc::new(BorrowCheckResult {
used_mut_nodes: bccx.used_mut_nodes.into_inner(), used_mut_nodes: bccx.used_mut_nodes.into_inner(),
signalled_any_error: bccx.signalled_any_error.into_inner(),
}) })
} }
@ -234,6 +237,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
owner_def_id, owner_def_id,
body, body,
used_mut_nodes: RefCell::new(FxHashSet()), used_mut_nodes: RefCell::new(FxHashSet()),
signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
}; };
let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg); let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg);
@ -257,6 +261,15 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
body: &'tcx hir::Body, body: &'tcx hir::Body,
used_mut_nodes: RefCell<FxHashSet<HirId>>, used_mut_nodes: RefCell<FxHashSet<HirId>>,
signalled_any_error: Cell<SignalledError>,
}
impl<'a, 'tcx: 'a> BorrowckCtxt<'a, 'tcx> {
fn signal_error(&self) {
self.signalled_any_error.set(SignalledError::SawSomeError);
}
} }
impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> { impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> {
@ -645,6 +658,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
.span_label(use_span, format!("use of possibly uninitialized `{}`", .span_label(use_span, format!("use of possibly uninitialized `{}`",
self.loan_path_to_string(lp))) self.loan_path_to_string(lp)))
.emit(); .emit();
self.signal_error();
return; return;
} }
_ => { _ => {
@ -760,6 +774,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
// not considered particularly helpful. // not considered particularly helpful.
err.emit(); err.emit();
self.signal_error();
} }
pub fn report_partial_reinitialization_of_uninitialized_structure( pub fn report_partial_reinitialization_of_uninitialized_structure(
@ -770,6 +785,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
&self.loan_path_to_string(lp), &self.loan_path_to_string(lp),
Origin::Ast) Origin::Ast)
.emit(); .emit();
self.signal_error();
} }
pub fn report_reassigned_immutable_variable(&self, pub fn report_reassigned_immutable_variable(&self,
@ -787,6 +803,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.loan_path_to_string(lp))); self.loan_path_to_string(lp)));
} }
err.emit(); err.emit();
self.signal_error();
} }
pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self, pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self,
@ -908,6 +925,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.tcx.hir.hir_to_node_id(err.cmt.hir_id) self.tcx.hir.hir_to_node_id(err.cmt.hir_id)
); );
db.emit(); db.emit();
self.signal_error();
} }
err_out_of_scope(super_scope, sub_scope, cause) => { err_out_of_scope(super_scope, sub_scope, cause) => {
let msg = match opt_loan_path(&err.cmt) { let msg = match opt_loan_path(&err.cmt) {
@ -1022,6 +1040,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
} }
db.emit(); db.emit();
self.signal_error();
} }
err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
let descr = self.cmt_to_path_or_string(err.cmt); let descr = self.cmt_to_path_or_string(err.cmt);
@ -1047,6 +1066,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
""); "");
db.emit(); db.emit();
self.signal_error();
} }
} }
} }
@ -1125,6 +1145,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
err.help("closures behind references must be called via `&mut`"); err.help("closures behind references must be called via `&mut`");
} }
err.emit(); err.emit();
self.signal_error();
} }
/// Given a type, if it is an immutable reference, return a suggestion to make it mutable /// Given a type, if it is an immutable reference, return a suggestion to make it mutable
@ -1307,6 +1328,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
cmt_path_or_string), cmt_path_or_string),
suggestion) suggestion)
.emit(); .emit();
self.signal_error();
} }
fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> { fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {