From 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:43 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_borrowck/src/lib.rs | 118 ++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 16 deletions(-) (limited to 'compiler/rustc_borrowck/src/lib.rs') diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 73ea7314b..0f591460e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,6 +1,7 @@ //! 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)] @@ -20,12 +21,15 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::vec_map::VecMap; -use rustc_errors::{Diagnostic, DiagnosticBuilder}; +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_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{ + DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, +}; +use rustc_macros::fluent_messages; use rustc_middle::mir::{ traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, @@ -43,6 +47,7 @@ use smallvec::SmallVec; use std::cell::OnceCell; use std::cell::RefCell; use std::collections::BTreeMap; +use std::ops::Deref; use std::rc::Rc; use rustc_mir_dataflow::impls::{ @@ -94,6 +99,9 @@ use nll::{PoloniusOutput, ToRegionVid}; use place_ext::PlaceExt; use places_conflict::{places_conflict, PlaceConflictBias}; use region_infer::RegionInferenceContext; +use renumber::RegionCtxt; + +fluent_messages! { "../locales/en-US.ftl" } // FIXME(eddyb) perhaps move this somewhere more centrally. #[derive(Debug)] @@ -167,10 +175,10 @@ fn do_mir_borrowck<'tcx>( return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option>>) { let def = input_body.source.with_opt_param().as_local().unwrap(); - debug!(?def); let tcx = infcx.tcx; + let infcx = BorrowckInferCtxt::new(infcx); let param_env = tcx.param_env(def.did); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); @@ -194,14 +202,14 @@ fn do_mir_borrowck<'tcx>( 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(e) = tables.tainted_by_errors { + if let Some(e) = input_body.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) - .map(|captured_place| { + let upvars: Vec<_> = tcx + .closure_captures(def.did) + .iter() + .map(|&captured_place| { let capture = captured_place.info.capture_kind; let by_ref = match capture { ty::UpvarCapture::ByValue => false, @@ -218,7 +226,7 @@ fn do_mir_borrowck<'tcx>( let mut body_owned = input_body.clone(); let mut promoted = input_promoted.clone(); let free_regions = - nll::replace_regions_in_mir(infcx, param_env, &mut body_owned, &mut promoted); + nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes let location_table_owned = LocationTable::new(body); @@ -256,7 +264,7 @@ fn do_mir_borrowck<'tcx>( opt_closure_req, nll_errors, } = nll::compute_regions( - infcx, + &infcx, free_regions, body, &promoted, @@ -271,12 +279,12 @@ fn do_mir_borrowck<'tcx>( // Dump MIR results into a file, if that is enabled. This let us // write unit-tests, as well as helping with debugging. - nll::dump_mir_results(infcx, &body, ®ioncx, &opt_closure_req); + nll::dump_mir_results(&infcx, &body, ®ioncx, &opt_closure_req); // We also have a `#[rustc_regions]` annotation that causes us to dump // information. nll::dump_annotation( - infcx, + &infcx, &body, ®ioncx, &opt_closure_req, @@ -320,7 +328,7 @@ fn do_mir_borrowck<'tcx>( if let Err((move_data, move_errors)) = move_data_results { let mut promoted_mbcx = MirBorrowckCtxt { - infcx, + infcx: &infcx, param_env, body: promoted_body, move_data: &move_data, @@ -349,7 +357,7 @@ fn do_mir_borrowck<'tcx>( } let mut mbcx = MirBorrowckCtxt { - infcx, + infcx: &infcx, param_env, body, move_data: &mdpe.move_data, @@ -481,8 +489,84 @@ pub struct BodyWithBorrowckFacts<'tcx> { pub location_table: LocationTable, } +pub struct BorrowckInferCtxt<'cx, 'tcx> { + pub(crate) infcx: &'cx InferCtxt<'tcx>, + pub(crate) reg_var_to_origin: RefCell>, +} + +impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { + pub(crate) fn new(infcx: &'cx InferCtxt<'tcx>) -> Self { + BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) } + } + + pub(crate) fn next_region_var( + &self, + origin: RegionVariableOrigin, + get_ctxt_fn: F, + ) -> ty::Region<'tcx> + where + 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)); + + if cfg!(debug_assertions) { + 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)); + } + + next_region + } + + #[instrument(skip(self, get_ctxt_fn), level = "debug")] + pub(crate) fn next_nll_region_var( + &self, + origin: NllRegionVariableOrigin, + get_ctxt_fn: F, + ) -> ty::Region<'tcx> + where + 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)); + + if cfg!(debug_assertions) { + 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)); + } + + next_region + } +} + +impl<'cx, 'tcx> Deref for BorrowckInferCtxt<'cx, 'tcx> { + type Target = InferCtxt<'tcx>; + + fn deref(&self) -> &'cx Self::Target { + self.infcx + } +} + struct MirBorrowckCtxt<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, + infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, param_env: ParamEnv<'tcx>, body: &'cx Body<'tcx>, move_data: &'cx MoveData<'tcx>, @@ -609,7 +693,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx StatementKind::AscribeUserType(..) // Doesn't have any language semantics | StatementKind::Coverage(..) - // Does not actually affect borrowck + // These do not actually affect borrowck + | StatementKind::ConstEvalCounter | StatementKind::StorageLive(..) => {} StatementKind::StorageDead(local) => { self.access_place( @@ -1277,6 +1362,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // in order to populate our used_mut set. match **aggregate_kind { AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => { + let def_id = def_id.expect_local(); let BorrowCheckResult { used_mut_upvars, .. } = self.infcx.tcx.mir_borrowck(def_id); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); -- cgit v1.2.3