diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
commit | 631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch) | |
tree | a1b87c8f8cad01cf18f7c5f57a08f102771ed303 /compiler/rustc_borrowck/src/lib.rs | |
parent | Adding debian version 1.69.0+dfsg1-1. (diff) | |
download | rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/lib.rs')
-rw-r--r-- | compiler/rustc_borrowck/src/lib.rs | 102 |
1 files changed, 37 insertions, 65 deletions
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0f591460e..a4b285a34 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,12 +1,11 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -#![allow(rustc::potential_query_instability)] #![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] @@ -18,14 +17,13 @@ extern crate rustc_middle; #[macro_use] extern crate tracing; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_data_structures::vec_map::VecMap; use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::{ DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; @@ -35,12 +33,13 @@ use rustc_middle::mir::{ Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; -use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; +use rustc_middle::mir::{ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt}; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; +use rustc_target::abi::FieldIdx; use either::Either; use smallvec::SmallVec; @@ -95,13 +94,13 @@ pub mod consumers; use borrow_set::{BorrowData, BorrowSet}; use dataflow::{BorrowIndex, BorrowckFlowState as Flows, BorrowckResults, Borrows}; -use nll::{PoloniusOutput, ToRegionVid}; +use nll::PoloniusOutput; use place_ext::PlaceExt; use places_conflict::{places_conflict, PlaceConflictBias}; use region_infer::RegionInferenceContext; use renumber::RegionCtxt; -fluent_messages! { "../locales/en-US.ftl" } +fluent_messages! { "../messages.ftl" } // FIXME(eddyb) perhaps move this somewhere more centrally. #[derive(Debug)] @@ -142,7 +141,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor debug!("Skipping borrowck because of injected body"); // Let's make up a borrowck result! Fun times! let result = BorrowCheckResult { - concrete_opaque_types: VecMap::new(), + concrete_opaque_types: FxIndexMap::default(), closure_requirements: None, used_mut_upvars: SmallVec::new(), tainted_by_errors: None, @@ -155,7 +154,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor 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 promoted: &IndexSlice<_, _> = &promoted.borrow(); let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0; debug!("mir_borrowck done"); @@ -171,7 +170,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor fn do_mir_borrowck<'tcx>( infcx: &InferCtxt<'tcx>, input_body: &Body<'tcx>, - input_promoted: &IndexVec<Promoted, Body<'tcx>>, + input_promoted: &IndexSlice<Promoted, Body<'tcx>>, return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { let def = input_body.source.with_opt_param().as_local().unwrap(); @@ -224,7 +223,7 @@ fn do_mir_borrowck<'tcx>( // be modified (in place) to contain non-lexical lifetimes. It // will have a lifetime tied to the inference context. let mut body_owned = input_body.clone(); - let mut promoted = input_promoted.clone(); + let mut promoted = input_promoted.to_owned(); let free_regions = nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes @@ -404,7 +403,7 @@ fn do_mir_borrowck<'tcx>( // Note that this set is expected to be small - only upvars from closures // would have a chance of erroneously adding non-user-defined mutable vars // to the set. - let temporary_used_locals: FxHashSet<Local> = mbcx + let temporary_used_locals: FxIndexSet<Local> = mbcx .used_mut .iter() .filter(|&local| !mbcx.body.local_decls[*local].is_user_variable()) @@ -491,7 +490,7 @@ pub struct BodyWithBorrowckFacts<'tcx> { pub struct BorrowckInferCtxt<'cx, 'tcx> { pub(crate) infcx: &'cx InferCtxt<'tcx>, - pub(crate) reg_var_to_origin: RefCell<FxHashMap<ty::RegionVid, RegionCtxt>>, + pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>, } impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { @@ -508,20 +507,13 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { F: Fn() -> RegionCtxt, { let next_region = self.infcx.next_region_var(origin); - let vid = next_region - .as_var() - .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + let vid = next_region.as_var(); - if cfg!(debug_assertions) { + if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); let ctxt = get_ctxt_fn(); let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); - let prev = var_to_origin.insert(vid, ctxt); - - // This only makes sense if not called in a canonicalization context. If this - // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin` - // or modify how we track nll region vars for that map. - assert!(matches!(prev, None)); + var_to_origin.insert(vid, ctxt); } next_region @@ -537,20 +529,13 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { F: Fn() -> RegionCtxt, { let next_region = self.infcx.next_nll_region_var(origin.clone()); - let vid = next_region - .as_var() - .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + let vid = next_region.as_var(); - if cfg!(debug_assertions) { + if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); let ctxt = get_ctxt_fn(); let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); - let prev = var_to_origin.insert(vid, ctxt); - - // This only makes sense if not called in a canonicalization context. If this - // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin` - // or modify how we track nll region vars for that map. - assert!(matches!(prev, None)); + var_to_origin.insert(vid, ctxt); } next_region @@ -588,7 +573,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> { /// borrow errors that is handled by the `reservation_error_reported` field as the inclusion /// of the `Span` type (while required to mute some errors) stops the muting of the reservation /// errors. - access_place_error_reported: FxHashSet<(Place<'tcx>, Span)>, + access_place_error_reported: FxIndexSet<(Place<'tcx>, Span)>, /// This field keeps track of when borrow conflict errors are reported /// for reservations, so that we don't report seemingly duplicate /// errors for corresponding activations. @@ -596,20 +581,20 @@ struct MirBorrowckCtxt<'cx, 'tcx> { // FIXME: ideally this would be a set of `BorrowIndex`, not `Place`s, // but it is currently inconvenient to track down the `BorrowIndex` // at the time we detect and report a reservation error. - reservation_error_reported: FxHashSet<Place<'tcx>>, + reservation_error_reported: FxIndexSet<Place<'tcx>>, /// This fields keeps track of the `Span`s that we have /// used to report extra information for `FnSelfUse`, to avoid /// unnecessarily verbose errors. - fn_self_span_reported: FxHashSet<Span>, + fn_self_span_reported: FxIndexSet<Span>, /// This field keeps track of errors reported in the checking of uninitialized variables, /// so that we don't report seemingly duplicate errors. - uninitialized_error_reported: FxHashSet<PlaceRef<'tcx>>, + uninitialized_error_reported: FxIndexSet<PlaceRef<'tcx>>, /// This field keeps track of all the local variables that are declared mut and are mutated. /// Used for the warning issued by an unused mutable local variable. - used_mut: FxHashSet<Local>, + used_mut: FxIndexSet<Local>, /// If the function we're checking is a closure, then we'll need to report back the list of /// mutable upvars that have been used. This field keeps track of them. - used_mut_upvars: SmallVec<[Field; 8]>, + used_mut_upvars: SmallVec<[FieldIdx; 8]>, /// Region inference context. This contains the results from region inference and lets us e.g. /// find out which CFG points are contained in each borrow region. regioncx: Rc<RegionInferenceContext<'tcx>>, @@ -628,7 +613,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> { /// Record the region names generated for each region in the given /// MIR def so that we can reuse them later in help/error messages. - region_names: RefCell<FxHashMap<RegionVid, RegionName>>, + region_names: RefCell<FxIndexMap<RegionVid, RegionName>>, /// The counter for generating new region names. next_region_name: RefCell<usize>, @@ -691,6 +676,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } // Only relevant for mir typeck StatementKind::AscribeUserType(..) + // Only relevant for unsafeck + | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) // These do not actually affect borrowck @@ -744,21 +731,12 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx flow_state, ); } - TerminatorKind::DropAndReplace { - place: drop_place, - value: new_value, - target: _, - unwind: _, - } => { - self.mutate_place(loc, (*drop_place, span), Deep, flow_state); - self.consume_operand(loc, (new_value, span), flow_state); - } TerminatorKind::Call { func, args, destination, target: _, - cleanup: _, + unwind: _, from_hir_call: _, fn_span: _, } => { @@ -768,7 +746,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } self.mutate_place(loc, (*destination, span), Deep, flow_state); } - TerminatorKind::Assert { cond, expected: _, msg, target: _, cleanup: _ } => { + TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.consume_operand(loc, (cond, span), flow_state); use rustc_middle::mir::AssertKind; if let AssertKind::BoundsCheck { len, index } = msg { @@ -788,7 +766,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx options: _, line_spans: _, destination: _, - cleanup: _, + unwind: _, } => { for op in operands { match op { @@ -819,7 +797,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } TerminatorKind::Goto { target: _ } - | TerminatorKind::Abort + | TerminatorKind::Terminate | TerminatorKind::Unreachable | TerminatorKind::Resume | TerminatorKind::Return @@ -863,11 +841,10 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } } - TerminatorKind::Abort + TerminatorKind::Terminate | TerminatorKind::Assert { .. } | TerminatorKind::Call { .. } | TerminatorKind::Drop { .. } - | TerminatorKind::DropAndReplace { .. } | TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ } | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } | TerminatorKind::Goto { .. } @@ -1185,12 +1162,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { this.buffer_error(err); } WriteKind::StorageDeadOrDrop => this - .report_borrowed_value_does_not_live_long_enough( - location, - borrow, - place_span, - Some(kind), - ), + .report_storage_dead_or_drop_of_borrowed(location, place_span, borrow), WriteKind::Mutate => { this.report_illegal_mutation_of_borrowed(location, place_span, borrow) } @@ -1367,7 +1339,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.infcx.tcx.mir_borrowck(def_id); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); for field in used_mut_upvars { - self.propagate_closure_used_mut_upvar(&operands[field.index()]); + self.propagate_closure_used_mut_upvar(&operands[*field]); } } AggregateKind::Adt(..) @@ -2302,7 +2274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. - fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<Field> { + fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<FieldIdx> { path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body()) } @@ -2334,7 +2306,7 @@ mod error { /// same primary span come out in a consistent order. buffered_move_errors: BTreeMap<Vec<MoveOutIndex>, (PlaceRef<'tcx>, DiagnosticBuilder<'tcx, ErrorGuaranteed>)>, - buffered_mut_errors: FxHashMap<Span, (DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)>, + buffered_mut_errors: FxIndexMap<Span, (DiagnosticBuilder<'tcx, ErrorGuaranteed>, usize)>, /// Diagnostics to be reported buffer. buffered: Vec<Diagnostic>, /// Set to Some if we emit an error during borrowck |