diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_borrowck/src/lib.rs | 76 |
1 files changed, 32 insertions, 44 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 3d8b07382..abfe253d4 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -3,7 +3,6 @@ #![allow(rustc::potential_query_instability)] #![feature(box_patterns)] #![feature(let_chains)] -#![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] @@ -19,15 +18,15 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_middle::mir::{ - traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem, - PlaceRef, VarDebugInfoContents, + traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, + Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; @@ -51,6 +50,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::MoveDataParamEnv; +use crate::session_diagnostics::VarNeedNotMut; + use self::diagnostics::{AccessKind, RegionName}; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -130,14 +131,11 @@ fn mir_borrowck<'tcx>( debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; - let opt_closure_req = tcx - .infer_ctxt() - .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner)) - .enter(|infcx| { - let input_body: &Body<'_> = &input_body.borrow(); - let promoted: &IndexVec<_, _> = &promoted.borrow(); - do_mir_borrowck(&infcx, input_body, promoted, false).0 - }); + let infcx = + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build(); + let input_body: &Body<'_> = &input_body.borrow(); + let promoted: &IndexVec<_, _> = &promoted.borrow(); + let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0; debug!("mir_borrowck done"); tcx.arena.alloc(opt_closure_req) @@ -149,8 +147,8 @@ fn mir_borrowck<'tcx>( /// region ids on which the borrow checking was performed together with Polonius /// facts. #[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")] -fn do_mir_borrowck<'a, 'tcx>( - infcx: &InferCtxt<'a, 'tcx>, +fn do_mir_borrowck<'tcx>( + infcx: &InferCtxt<'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexVec<Promoted, Body<'tcx>>, return_body_with_facts: bool, @@ -425,17 +423,9 @@ fn do_mir_borrowck<'a, 'tcx>( continue; } - tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| { - let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - lint.build("variable does not need to be mutable") - .span_suggestion_short( - mut_span, - "remove this `mut`", - "", - Applicability::MachineApplicable, - ) - .emit(); - }) + let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); + + tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) } let tainted_by_errors = mbcx.emit_errors(); @@ -481,7 +471,7 @@ pub struct BodyWithBorrowckFacts<'tcx> { } struct MirBorrowckCtxt<'cx, 'tcx> { - infcx: &'cx InferCtxt<'cx, 'tcx>, + infcx: &'cx InferCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &'cx Body<'tcx>, move_data: &'cx MoveData<'tcx>, @@ -597,22 +587,19 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx flow_state, ); } - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - .. - }) => { - span_bug!( + StatementKind::Intrinsic(box ref kind) => match kind { + NonDivergingIntrinsic::Assume(op) => self.consume_operand(location, (op, span), flow_state), + NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!( span, "Unexpected CopyNonOverlapping, should only appear after lower_intrinsics", ) } - StatementKind::Nop + // Only relevant for mir typeck + StatementKind::AscribeUserType(..) + // Doesn't have any language semantics | StatementKind::Coverage(..) - | StatementKind::AscribeUserType(..) - | StatementKind::Retag { .. } - | StatementKind::StorageLive(..) => { - // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant - // to borrow check. - } + // Does not actually affect borrowck + | StatementKind::StorageLive(..) => {} StatementKind::StorageDead(local) => { self.access_place( location, @@ -622,7 +609,10 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx flow_state, ); } - StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { + StatementKind::Nop + | StatementKind::Retag { .. } + | StatementKind::Deinit(..) + | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } } @@ -982,6 +972,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } + #[instrument(level = "debug", skip(self, flow_state))] fn check_access_for_conflict( &mut self, location: Location, @@ -990,11 +981,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { rw: ReadOrWrite, flow_state: &Flows<'cx, 'tcx>, ) -> bool { - debug!( - "check_access_for_conflict(location={:?}, place_span={:?}, sd={:?}, rw={:?})", - location, place_span, sd, rw, - ); - let mut error_reported = false; let tcx = self.infcx.tcx; let body = self.body; @@ -1458,13 +1444,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Checks whether a borrow of this place is invalidated when the function /// exits + #[instrument(level = "debug", skip(self))] fn check_for_invalidation_at_exit( &mut self, location: Location, borrow: &BorrowData<'tcx>, span: Span, ) { - debug!("check_for_invalidation_at_exit({:?})", borrow); let place = borrow.borrowed_place; let mut root_place = PlaceRef { local: place.local, projection: &[] }; @@ -1791,6 +1777,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for (place_base, elem) in place.iter_projections().rev() { match elem { ProjectionElem::Index(_/*operand*/) | + ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } | // assigning to P[i] requires P to be valid. ProjectionElem::Downcast(_/*adt_def*/, _/*variant_idx*/) => @@ -2182,6 +2169,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } + | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Downcast(..) => { let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { |