diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 321b18c9b78b2..752ff8e6f586b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -19,6 +19,7 @@ use std::borrow::Cow; use std::cell::{OnceCell, RefCell}; use std::marker::PhantomData; use std::ops::{ControlFlow, Deref}; +use std::rc::Rc; use borrow_set::LocalsStateAtExit; use root_cx::BorrowCheckRootCtxt; @@ -44,6 +45,7 @@ use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces} use rustc_mir_dataflow::move_paths::{ InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex, }; +use rustc_mir_dataflow::points::DenseLocationMap; use rustc_mir_dataflow::{Analysis, Results, ResultsVisitor, visit_results}; use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; @@ -60,11 +62,14 @@ use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; use crate::polonius::PoloniusDiagnosticsContext; -use crate::polonius::legacy::{PoloniusLocationTable, PoloniusOutput}; +use crate::polonius::legacy::{ + PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, +}; use crate::prefixes::PrefixSet; use crate::region_infer::RegionInferenceContext; use crate::renumber::RegionCtxt; use crate::session_diagnostics::VarNeedNotMut; +use crate::type_check::MirTypeckResults; mod borrow_set; mod borrowck_errors; @@ -321,7 +326,34 @@ fn do_mir_borrowck<'tcx>( let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure(); let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data); - // Compute non-lexical lifetimes. + let location_map = Rc::new(DenseLocationMap::new(body)); + + let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input()) + || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); + let mut polonius_facts = + (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default()); + + // Run the MIR type-checker. + let MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + polonius_context, + } = type_check::type_check( + root_cx, + &infcx, + body, + &promoted, + universal_regions, + &location_table, + &borrow_set, + &mut polonius_facts, + &move_data, + Rc::clone(&location_map), + ); + + // Compute non-lexical lifetimes using the constraints computed + // by typechecking the MIR body. let nll::NllOutput { regioncx, polonius_input, @@ -332,14 +364,19 @@ fn do_mir_borrowck<'tcx>( } = nll::compute_regions( root_cx, &infcx, - universal_regions, body, - &promoted, &location_table, &move_data, &borrow_set, + location_map, + universal_region_relations, + constraints, + polonius_facts, + polonius_context, ); + regioncx.infer_opaque_types(root_cx, &infcx, opaque_type_values); + // Dump MIR results into a file, if that is enabled. This lets us // write unit-tests, as well as helping with debugging. nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set); diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 41f67e78930f0..ca6092e70d253 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -5,7 +5,8 @@ use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; -use polonius_engine::{Algorithm, Output}; +use polonius_engine::{Algorithm, AllFacts, Output}; +use rustc_data_structures::frozen::Frozen; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options}; use rustc_middle::mir::{Body, PassWhere, Promoted, create_dump_file, dump_enabled, dump_mir}; @@ -18,14 +19,16 @@ use rustc_span::sym; use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; +use crate::consumers::RustcFacts; use crate::diagnostics::RegionErrors; use crate::handle_placeholders::compute_sccs_applying_placeholder_outlives_constraints; -use crate::polonius::PoloniusDiagnosticsContext; use crate::polonius::legacy::{ PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, }; +use crate::polonius::{PoloniusContext, PoloniusDiagnosticsContext}; use crate::region_infer::RegionInferenceContext; -use crate::type_check::{self, MirTypeckResults}; +use crate::type_check::MirTypeckRegionConstraints; +use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; use crate::{ BorrowCheckRootCtxt, BorrowckInferCtxt, ClosureOutlivesSubject, ClosureRegionRequirements, @@ -76,41 +79,18 @@ pub(crate) fn replace_regions_in_mir<'tcx>( pub(crate) fn compute_regions<'tcx>( root_cx: &mut BorrowCheckRootCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>, - universal_regions: UniversalRegions<'tcx>, body: &Body<'tcx>, - promoted: &IndexSlice>, location_table: &PoloniusLocationTable, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, + location_map: Rc, + universal_region_relations: Frozen>, + constraints: MirTypeckRegionConstraints<'tcx>, + mut polonius_facts: Option>, + polonius_context: Option, ) -> NllOutput<'tcx> { - let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); - let polonius_input = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_input()) - || is_polonius_legacy_enabled; let polonius_output = root_cx.consumer.as_ref().map_or(false, |c| c.polonius_output()) - || is_polonius_legacy_enabled; - let mut polonius_facts = - (polonius_input || PoloniusFacts::enabled(infcx.tcx)).then_some(PoloniusFacts::default()); - - let location_map = Rc::new(DenseLocationMap::new(body)); - - // Run the MIR type-checker. - let MirTypeckResults { - constraints, - universal_region_relations, - opaque_type_values, - polonius_context, - } = type_check::type_check( - root_cx, - infcx, - body, - promoted, - universal_regions, - location_table, - borrow_set, - &mut polonius_facts, - move_data, - Rc::clone(&location_map), - ); + || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( constraints, @@ -173,8 +153,6 @@ pub(crate) fn compute_regions<'tcx>( infcx.set_tainted_by_errors(guar); } - regioncx.infer_opaque_types(root_cx, infcx, opaque_type_values); - NllOutput { regioncx, polonius_input: polonius_facts.map(Box::new),