summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/lib.rs')
-rw-r--r--compiler/rustc_borrowck/src/lib.rs115
1 files changed, 68 insertions, 47 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index abfe253d4..74b4e4a0c 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -18,7 +18,8 @@ extern crate tracing;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_data_structures::vec_map::VecMap;
+use rustc_errors::{Diagnostic, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet;
@@ -82,7 +83,7 @@ mod type_check;
mod universal_regions;
mod used_muts;
-// A public API provided for the Rust compiler consumers.
+/// A public API provided for the Rust compiler consumers.
pub mod consumers;
use borrow_set::{BorrowData, BorrowSet};
@@ -129,6 +130,19 @@ fn mir_borrowck<'tcx>(
) -> &'tcx BorrowCheckResult<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
+
+ if input_body.borrow().should_skip() {
+ debug!("Skipping borrowck because of injected body");
+ // Let's make up a borrowck result! Fun times!
+ let result = BorrowCheckResult {
+ concrete_opaque_types: VecMap::new(),
+ closure_requirements: None,
+ used_mut_upvars: SmallVec::new(),
+ tainted_by_errors: None,
+ };
+ return tcx.arena.alloc(result);
+ }
+
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let infcx =
@@ -178,13 +192,13 @@ fn do_mir_borrowck<'tcx>(
}
}
- let mut errors = error::BorrowckErrors::new();
+ let mut errors = error::BorrowckErrors::new(infcx.tcx);
// Gather the upvars of a closure, if any.
let tables = tcx.typeck_opt_const_arg(def);
- if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors {
- infcx.set_tainted_by_errors();
- errors.set_tainted_by_errors();
+ if let Some(e) = tables.tainted_by_errors {
+ infcx.set_tainted_by_errors(e);
+ errors.set_tainted_by_errors(e);
}
let upvars: Vec<_> = tables
.closure_min_captures_flattened(def.did)
@@ -564,12 +578,12 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
self.check_activations(location, span, flow_state);
match &stmt.kind {
- StatementKind::Assign(box (lhs, ref rhs)) => {
+ StatementKind::Assign(box (lhs, rhs)) => {
self.consume_rvalue(location, (rhs, span), flow_state);
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
}
- StatementKind::FakeRead(box (_, ref place)) => {
+ StatementKind::FakeRead(box (_, place)) => {
// Read for match doesn't access any memory and is used to
// assert that a place is safe and live. So we don't have to
// do any checks here.
@@ -587,7 +601,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
flow_state,
);
}
- StatementKind::Intrinsic(box ref kind) => match kind {
+ StatementKind::Intrinsic(box kind) => match kind {
NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state),
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
span,
@@ -629,8 +643,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
self.check_activations(loc, span, flow_state);
- match term.kind {
- TerminatorKind::SwitchInt { ref discr, switch_ty: _, targets: _ } => {
+ match &term.kind {
+ TerminatorKind::SwitchInt { discr, switch_ty: _, targets: _ } => {
self.consume_operand(loc, (discr, span), flow_state);
}
TerminatorKind::Drop { place, target: _, unwind: _ } => {
@@ -642,7 +656,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
self.access_place(
loc,
- (place, span),
+ (*place, span),
(AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
LocalMutationIsAllowed::Yes,
flow_state,
@@ -650,16 +664,16 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
}
TerminatorKind::DropAndReplace {
place: drop_place,
- value: ref new_value,
+ value: new_value,
target: _,
unwind: _,
} => {
- self.mutate_place(loc, (drop_place, span), Deep, flow_state);
+ self.mutate_place(loc, (*drop_place, span), Deep, flow_state);
self.consume_operand(loc, (new_value, span), flow_state);
}
TerminatorKind::Call {
- ref func,
- ref args,
+ func,
+ args,
destination,
target: _,
cleanup: _,
@@ -670,43 +684,43 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
for arg in args {
self.consume_operand(loc, (arg, span), flow_state);
}
- self.mutate_place(loc, (destination, span), Deep, flow_state);
+ self.mutate_place(loc, (*destination, span), Deep, flow_state);
}
- TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
+ TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => {
self.consume_operand(loc, (cond, span), flow_state);
use rustc_middle::mir::AssertKind;
- if let AssertKind::BoundsCheck { ref len, ref index } = *msg {
+ if let AssertKind::BoundsCheck { len, index } = msg {
self.consume_operand(loc, (len, span), flow_state);
self.consume_operand(loc, (index, span), flow_state);
}
}
- TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => {
+ TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
self.consume_operand(loc, (value, span), flow_state);
- self.mutate_place(loc, (resume_arg, span), Deep, flow_state);
+ self.mutate_place(loc, (*resume_arg, span), Deep, flow_state);
}
TerminatorKind::InlineAsm {
template: _,
- ref operands,
+ operands,
options: _,
line_spans: _,
destination: _,
cleanup: _,
} => {
for op in operands {
- match *op {
- InlineAsmOperand::In { reg: _, ref value } => {
+ match op {
+ InlineAsmOperand::In { reg: _, value } => {
self.consume_operand(loc, (value, span), flow_state);
}
InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
if let Some(place) = place {
- self.mutate_place(loc, (place, span), Shallow(None), flow_state);
+ self.mutate_place(loc, (*place, span), Shallow(None), flow_state);
}
}
- InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
+ InlineAsmOperand::InOut { reg: _, late: _, in_value, out_place } => {
self.consume_operand(loc, (in_value, span), flow_state);
- if let Some(out_place) = out_place {
+ if let &Some(out_place) = out_place {
self.mutate_place(
loc,
(out_place, span),
@@ -1150,8 +1164,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(rvalue, span): (&'cx Rvalue<'tcx>, Span),
flow_state: &Flows<'cx, 'tcx>,
) {
- match *rvalue {
- Rvalue::Ref(_ /*rgn*/, bk, place) => {
+ match rvalue {
+ &Rvalue::Ref(_ /*rgn*/, bk, place) => {
let access_kind = match bk {
BorrowKind::Shallow => {
(Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
@@ -1189,7 +1203,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}
- Rvalue::AddressOf(mutability, place) => {
+ &Rvalue::AddressOf(mutability, place) => {
let access_kind = match mutability {
Mutability::Mut => (
Deep,
@@ -1218,14 +1232,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Rvalue::ThreadLocalRef(_) => {}
- Rvalue::Use(ref operand)
- | Rvalue::Repeat(ref operand, _)
- | Rvalue::UnaryOp(_ /*un_op*/, ref operand)
- | Rvalue::Cast(_ /*cast_kind*/, ref operand, _ /*ty*/)
- | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => {
+ Rvalue::Use(operand)
+ | Rvalue::Repeat(operand, _)
+ | Rvalue::UnaryOp(_ /*un_op*/, operand)
+ | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/)
+ | Rvalue::ShallowInitBox(operand, _ /*ty*/) => {
self.consume_operand(location, (operand, span), flow_state)
}
- Rvalue::CopyForDeref(place) => {
+
+ &Rvalue::CopyForDeref(place) => {
self.access_place(
location,
(place, span),
@@ -1243,7 +1258,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}
- Rvalue::Len(place) | Rvalue::Discriminant(place) => {
+ &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
let af = match *rvalue {
Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
Rvalue::Discriminant(..) => None,
@@ -1264,8 +1279,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
}
- Rvalue::BinaryOp(_bin_op, box (ref operand1, ref operand2))
- | Rvalue::CheckedBinaryOp(_bin_op, box (ref operand1, ref operand2)) => {
+ Rvalue::BinaryOp(_bin_op, box (operand1, operand2))
+ | Rvalue::CheckedBinaryOp(_bin_op, box (operand1, operand2)) => {
self.consume_operand(location, (operand1, span), flow_state);
self.consume_operand(location, (operand2, span), flow_state);
}
@@ -1274,7 +1289,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// nullary ops take no dynamic input; no borrowck effect.
}
- Rvalue::Aggregate(ref aggregate_kind, ref operands) => {
+ Rvalue::Aggregate(aggregate_kind, operands) => {
// We need to report back the list of mutable upvars that were
// moved into the closure and subsequently used by the closure,
// in order to populate our used_mut set.
@@ -2246,6 +2261,7 @@ mod error {
use super::*;
pub struct BorrowckErrors<'tcx> {
+ tcx: TyCtxt<'tcx>,
/// This field keeps track of move errors that are to be reported for given move indices.
///
/// There are situations where many errors can be reported for a single move out (see #53807)
@@ -2268,19 +2284,24 @@ mod error {
tainted_by_errors: Option<ErrorGuaranteed>,
}
- impl BorrowckErrors<'_> {
- pub fn new() -> Self {
+ impl<'tcx> BorrowckErrors<'tcx> {
+ pub fn new(tcx: TyCtxt<'tcx>) -> Self {
BorrowckErrors {
+ tcx,
buffered_move_errors: BTreeMap::new(),
buffered: Default::default(),
tainted_by_errors: None,
}
}
- // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is
- // set before any emission actually happens (weakening the guarantee).
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) {
- self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ if let None = self.tainted_by_errors {
+ self.tainted_by_errors = Some(
+ self.tcx
+ .sess
+ .delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"),
+ )
+ }
t.buffer(&mut self.buffered);
}
@@ -2288,8 +2309,8 @@ mod error {
t.buffer(&mut self.buffered);
}
- pub fn set_tainted_by_errors(&mut self) {
- self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
+ pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) {
+ self.tainted_by_errors = Some(e);
}
}