From 1f1c575c5f678e3d20c653d1290b24351ecca103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 7 Dec 2018 06:59:27 +0100 Subject: [PATCH 1/2] Make the 'a lifetime on TyCtxt useless --- src/librustc/infer/mod.rs | 7 +++-- src/librustc/ty/context.rs | 51 +++++++++++++++++++------------ src/librustc/ty/mod.rs | 2 +- src/librustc/ty/query/plumbing.rs | 2 +- src/librustc_driver/driver.rs | 13 +++----- src/librustc_driver/lib.rs | 1 - src/librustc_driver/pretty.rs | 14 +++------ src/librustc_driver/test.rs | 4 +-- src/librustdoc/core.rs | 4 +-- 9 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b1a13354b7cdb..5c97087351b4f 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -37,7 +37,7 @@ use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::fold::TypeFoldable; use ty::relate::RelateResult; use ty::subst::{Kind, Substs}; -use ty::{self, GenericParamDefKind, Ty, TyCtxt}; +use ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners}; use ty::{FloatVid, IntVid, TyVid}; use util::nodemap::FxHashMap; @@ -471,6 +471,7 @@ impl fmt::Display for FixupError { pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { global_tcx: TyCtxt<'a, 'gcx, 'gcx>, arena: SyncDroplessArena, + interners: Option>, fresh_tables: Option>>, } @@ -479,6 +480,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { InferCtxtBuilder { global_tcx: self, arena: SyncDroplessArena::default(), + interners: None, fresh_tables: None, } } @@ -519,10 +521,11 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { let InferCtxtBuilder { global_tcx, ref arena, + ref mut interners, ref fresh_tables, } = *self; let in_progress_tables = fresh_tables.as_ref(); - global_tcx.enter_local(arena, |tcx| { + global_tcx.enter_local(arena, interners, |tcx| { f(InferCtxt { tcx, in_progress_tables, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index a3db3a02aad92..94415315a11b7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -72,6 +72,7 @@ use std::ops::{Deref, Bound}; use std::iter; use std::sync::mpsc; use std::sync::Arc; +use std::marker::PhantomData; use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; @@ -86,6 +87,7 @@ use hir; pub struct AllArenas<'tcx> { pub global: WorkerLocal>, pub interner: SyncDroplessArena, + global_ctxt: Option>, } impl<'tcx> AllArenas<'tcx> { @@ -93,6 +95,7 @@ impl<'tcx> AllArenas<'tcx> { AllArenas { global: WorkerLocal::new(|_| GlobalArenas::default()), interner: SyncDroplessArena::default(), + global_ctxt: None, } } } @@ -869,12 +872,13 @@ pub struct FreeRegionInfo { /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html #[derive(Copy, Clone)] pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> { - gcx: &'a GlobalCtxt<'gcx>, - interners: &'a CtxtInterners<'tcx> + gcx: &'gcx GlobalCtxt<'gcx>, + interners: &'tcx CtxtInterners<'tcx>, + dummy: PhantomData<&'a ()>, } -impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> { - type Target = &'a GlobalCtxt<'gcx>; +impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> { + type Target = &'gcx GlobalCtxt<'gcx>; #[inline(always)] fn deref(&self) -> &Self::Target { &self.gcx @@ -964,10 +968,11 @@ pub struct GlobalCtxt<'tcx> { impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Get the global TyCtxt. #[inline] - pub fn global_tcx(self) -> TyCtxt<'a, 'gcx, 'gcx> { + pub fn global_tcx(self) -> TyCtxt<'gcx, 'gcx, 'gcx> { TyCtxt { gcx: self.gcx, interners: &self.gcx.global_interners, + dummy: PhantomData, } } @@ -1105,7 +1110,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, - arenas: &'tcx AllArenas<'tcx>, + arenas: &'tcx mut AllArenas<'tcx>, resolutions: ty::Resolutions, hir: hir_map::Map<'tcx>, on_disk_query_result_cache: query::OnDiskCache<'tcx>, @@ -1166,7 +1171,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Lrc::new(StableVec::new(v))); } - let gcx = &GlobalCtxt { + arenas.global_ctxt = Some(GlobalCtxt { sess: s, cstore, global_arenas: &arenas.global, @@ -1209,7 +1214,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { alloc_map: Lock::new(interpret::AllocMap::new()), tx_to_llvm_workers: Lock::new(tx), output_filenames: Arc::new(output_filenames.clone()), - }; + }); + + let gcx = arenas.global_ctxt.as_ref().unwrap(); sync::assert_send_val(&gcx); @@ -1609,20 +1616,23 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } } -impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { +impl<'gcx> GlobalCtxt<'gcx> { /// Call the closure with a local `TyCtxt` using the given arena. - pub fn enter_local( - &self, + pub fn enter_local<'tcx, F, R>( + &'gcx self, arena: &'tcx SyncDroplessArena, + interners: &'tcx mut Option>, f: F ) -> R where - F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R + F: FnOnce(TyCtxt<'tcx, 'gcx, 'tcx>) -> R, + 'gcx: 'tcx, { - let interners = CtxtInterners::new(arena); + *interners = Some(CtxtInterners::new(&arena)); let tcx = TyCtxt { gcx: self, - interners: &interners, + interners: interners.as_ref().unwrap(), + dummy: PhantomData, }; ty::tls::with_related_context(tcx.global_tcx(), |icx| { let new_icx = ty::tls::ImplicitCtxt { @@ -1631,8 +1641,8 @@ impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { layout_depth: icx.layout_depth, task: icx.task, }; - ty::tls::enter_context(&new_icx, |new_icx| { - f(new_icx.tcx) + ty::tls::enter_context(&new_icx, |_| { + f(tcx) }) }) } @@ -1872,6 +1882,7 @@ pub mod tls { use std::fmt; use std::mem; + use std::marker::PhantomData; use syntax_pos; use ty::query; use errors::{Diagnostic, TRACK_DIAGNOSTICS}; @@ -1891,10 +1902,10 @@ pub mod tls { /// you should also have access to an ImplicitCtxt through the functions /// in this module. #[derive(Clone)] - pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { + pub struct ImplicitCtxt<'a, 'gcx: 'tcx, 'tcx> { /// The current TyCtxt. Initially created by `enter_global` and updated /// by `enter_local` with a new local interner - pub tcx: TyCtxt<'a, 'gcx, 'tcx>, + pub tcx: TyCtxt<'tcx, 'gcx, 'tcx>, /// The current query job, if any. This is updated by start_job in /// ty::query::plumbing when executing a query @@ -2008,7 +2019,7 @@ pub mod tls { /// creating a initial TyCtxt and ImplicitCtxt. /// This happens once per rustc session and TyCtxts only exists /// inside the `f` function. - pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R + pub fn enter_global<'gcx, F, R>(gcx: &'gcx GlobalCtxt<'gcx>, f: F) -> R where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R { with_thread_locals(|| { @@ -2024,6 +2035,7 @@ pub mod tls { let tcx = TyCtxt { gcx, interners: &gcx.global_interners, + dummy: PhantomData, }; let icx = ImplicitCtxt { tcx, @@ -2053,6 +2065,7 @@ pub mod tls { let tcx = TyCtxt { gcx, interners: &gcx.global_interners, + dummy: PhantomData, }; let icx = ImplicitCtxt { query: None, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a1fc949137dde..91e1df3f74b3a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -82,7 +82,7 @@ pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; pub use self::context::{TyCtxt, FreeRegionInfo, GlobalArenas, AllArenas, tls, keep_local}; -pub use self::context::{Lift, TypeckTables}; +pub use self::context::{Lift, TypeckTables, CtxtInterners}; pub use self::instance::{Instance, InstanceDef}; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 5f33d466c4a19..f946ce85adcea 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -197,7 +197,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { let r = tls::with_related_context(tcx, move |current_icx| { // Update the ImplicitCtxt to point to our new query job let new_icx = tls::ImplicitCtxt { - tcx, + tcx: tcx.global_tcx(), query: Some(self.job.clone()), layout_depth: current_icx.layout_depth, task: current_icx.task, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f2edcdc1bac35..0f6799710f18e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -246,8 +246,6 @@ pub fn compile_input( } } - let arenas = AllArenas::new(); - // Construct the HIR map let hir_map = time(sess, "indexing hir", || { hir_map::map_crate(sess, cstore, &mut hir_forest, &defs) @@ -263,7 +261,6 @@ pub fn compile_input( sess, outdir, output, - &arenas, &cstore, &hir_map, &analysis, @@ -284,6 +281,8 @@ pub fn compile_input( None }; + let mut arenas = AllArenas::new(); + phase_3_run_analysis_passes( &*codegen_backend, control, @@ -292,7 +291,7 @@ pub fn compile_input( hir_map, analysis, resolutions, - &arenas, + &mut arenas, &crate_name, &outputs, |tcx, analysis, rx, result| { @@ -533,7 +532,6 @@ pub struct CompileState<'a, 'tcx: 'a> { pub output_filenames: Option<&'a OutputFilenames>, pub out_dir: Option<&'a Path>, pub out_file: Option<&'a Path>, - pub arenas: Option<&'tcx AllArenas<'tcx>>, pub expanded_crate: Option<&'a ast::Crate>, pub hir_crate: Option<&'a hir::Crate>, pub hir_map: Option<&'a hir_map::Map<'tcx>>, @@ -549,7 +547,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session, out_dir: out_dir.as_ref().map(|s| &**s), out_file: None, - arenas: None, krate: None, registry: None, cstore: None, @@ -605,7 +602,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session: &'tcx Session, out_dir: &'a Option, out_file: &'a Option, - arenas: &'tcx AllArenas<'tcx>, cstore: &'tcx CStore, hir_map: &'a hir_map::Map<'tcx>, analysis: &'a ty::CrateAnalysis, @@ -617,7 +613,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { ) -> Self { CompileState { crate_name: Some(crate_name), - arenas: Some(arenas), cstore: Some(cstore), hir_map: Some(hir_map), analysis: Some(analysis), @@ -1216,7 +1211,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>( hir_map: hir_map::Map<'tcx>, mut analysis: ty::CrateAnalysis, resolutions: Resolutions, - arenas: &'tcx AllArenas<'tcx>, + arenas: &'tcx mut AllArenas<'tcx>, name: &str, output_filenames: &OutputFilenames, f: F, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 39777e0a65b50..041c8aa2f57ad 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -911,7 +911,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { &state.expanded_crate.take().unwrap(), state.crate_name.unwrap(), ppm, - state.arenas.unwrap(), state.output_filenames.unwrap(), opt_uii.clone(), state.out_file); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index b41b0d081ced9..bc991016bbee5 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -202,7 +202,6 @@ impl PpSourceMode { hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, - arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, id: &str, f: F @@ -228,6 +227,7 @@ impl PpSourceMode { PpmTyped => { let control = &driver::CompileController::basic(); let codegen_backend = ::get_codegen_backend(sess); + let mut arenas = AllArenas::new(); abort_on_err(driver::phase_3_run_analysis_passes(&*codegen_backend, control, sess, @@ -235,7 +235,7 @@ impl PpSourceMode { hir_map.clone(), analysis.clone(), resolutions.clone(), - arenas, + &mut arenas, id, output_filenames, |tcx, _, _, _| { @@ -977,7 +977,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, krate: &ast::Crate, crate_name: &str, ppm: PpMode, - arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, opt_uii: Option, ofile: Option<&Path>) { @@ -988,7 +987,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, analysis, resolutions, crate_name, - arenas, output_filenames, ppm, opt_uii, @@ -1026,7 +1024,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arenas, output_filenames, crate_name, move |annotation, krate| { @@ -1050,7 +1047,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arenas, output_filenames, crate_name, move |_annotation, krate| { @@ -1066,7 +1062,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arenas, output_filenames, crate_name, move |annotation, _| { @@ -1100,7 +1095,6 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map, analysis, resolutions, - arenas, output_filenames, crate_name, move |_annotation, _krate| { @@ -1130,7 +1124,6 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, crate_name: &str, - arenas: &'tcx AllArenas<'tcx>, output_filenames: &OutputFilenames, ppm: PpMode, uii: Option, @@ -1147,6 +1140,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, let control = &driver::CompileController::basic(); let codegen_backend = ::get_codegen_backend(sess); + let mut arenas = AllArenas::new(); abort_on_err(driver::phase_3_run_analysis_passes(&*codegen_backend, control, sess, @@ -1154,7 +1148,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map.clone(), analysis.clone(), resolutions.clone(), - arenas, + &mut arenas, crate_name, output_filenames, |tcx, _, _, _| { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index f9d49f03ee044..5b337fbf5bef3 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -151,7 +151,7 @@ fn test_env_with_pool( ).expect("phase 2 aborted") }; - let arenas = ty::AllArenas::new(); + let mut arenas = ty::AllArenas::new(); let hir_map = hir_map::map_crate(&sess, &cstore, &mut hir_forest, &defs); // Run just enough stuff to build a tcx. @@ -168,7 +168,7 @@ fn test_env_with_pool( &cstore, ty::query::Providers::default(), ty::query::Providers::default(), - &arenas, + &mut arenas, resolutions, hir_map, OnDiskCache::new_empty(sess.source_map()), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 047d35579444f..8af9697b312d0 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -485,7 +485,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt glob_map: if resolver.make_glob_map { Some(resolver.glob_map.clone()) } else { None }, }; - let arenas = AllArenas::new(); + let mut arenas = AllArenas::new(); let hir_map = hir_map::map_crate(&sess, &*cstore, &mut hir_forest, &defs); let output_filenames = driver::build_output_filenames(&input, &None, @@ -501,7 +501,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt hir_map, analysis, resolutions, - &arenas, + &mut arenas, &name, &output_filenames, |tcx, analysis, _, result| { From d0190d348b4840e6a3e9632fae7453ee77d5a15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 13 Dec 2018 03:32:44 +0100 Subject: [PATCH 2/2] Some changes --- src/librustc/infer/mod.rs | 2 ++ src/librustc/ty/context.rs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 5c97087351b4f..bd9326120edc4 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -525,6 +525,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { ref fresh_tables, } = *self; let in_progress_tables = fresh_tables.as_ref(); + // Check that we haven't entered before + assert!(interners.is_none()); global_tcx.enter_local(arena, interners, |tcx| { f(InferCtxt { tcx, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 94415315a11b7..fdc78791e02b4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1618,6 +1618,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { impl<'gcx> GlobalCtxt<'gcx> { /// Call the closure with a local `TyCtxt` using the given arena. + /// `interners` is a slot passed so we can create a CtxtInterners + /// with the same lifetime as `arena`. pub fn enter_local<'tcx, F, R>( &'gcx self, arena: &'tcx SyncDroplessArena, @@ -2020,7 +2022,7 @@ pub mod tls { /// This happens once per rustc session and TyCtxts only exists /// inside the `f` function. pub fn enter_global<'gcx, F, R>(gcx: &'gcx GlobalCtxt<'gcx>, f: F) -> R - where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R + where F: FnOnce(TyCtxt<'gcx, 'gcx, 'gcx>) -> R { with_thread_locals(|| { // Update GCX_PTR to indicate there's a GlobalCtxt available