From b2ea54d2c6277f90312ae6a5de5f9165def99ffe Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 May 2016 14:14:41 -0400 Subject: [PATCH 01/16] trans: Split LocalCrateContext ownership out of SharedCrateContext. --- src/librustc_trans/base.rs | 26 ++-- src/librustc_trans/context.rs | 259 ++++++++++++++++++---------------- 2 files changed, 151 insertions(+), 134 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index dd453bf996916..98a84205930f8 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -68,7 +68,7 @@ use common::{node_id_type, fulfill_obligation}; use common::{type_is_immediate, type_is_zero_size, val_ty}; use common; use consts; -use context::SharedCrateContext; +use context::{SharedCrateContext, CrateContextList}; use controlflow; use datum; use debuginfo::{self, DebugLoc, ToDebugLoc}; @@ -2522,7 +2522,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>, /// Find any symbols that are defined in one compilation unit, but not declared /// in any other compilation unit. Give these symbols internal linkage. -fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) { +fn internalize_symbols(cx: &CrateContextList, reachable: &HashSet<&str>) { unsafe { let mut declared = HashSet::new(); @@ -2577,12 +2577,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) { // when using MSVC linker. We do this only for data, as linker can fix up // code references on its own. // See #26591, #27438 -fn create_imps(cx: &SharedCrateContext) { +fn create_imps(cx: &CrateContextList) { // The x86 ABI seems to require that leading underscores are added to symbol // names, so we need an extra underscore on 32-bit. There's also a leading // '\x01' here which disables LLVM's symbol mangling (e.g. no extra // underscores added in front). - let prefix = if cx.sess().target.target.target_pointer_width == "32" { + let prefix = if cx.shared().sess().target.target.target_pointer_width == "32" { "\x01__imp__" } else { "\x01__imp_" @@ -2714,10 +2714,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, let link_meta = link::build_link_meta(&tcx, name); - let codegen_units = tcx.sess.opts.cg.codegen_units; - let shared_ccx = SharedCrateContext::new(&link_meta.crate_name, - codegen_units, - tcx, + let shared_ccx = SharedCrateContext::new(tcx, &mir_map, export_map, Sha256::new(), @@ -2726,8 +2723,11 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, check_overflow, check_dropflag); + let codegen_units = tcx.sess.opts.cg.codegen_units; + let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units); + { - let ccx = shared_ccx.get_ccx(0); + let ccx = crate_context_list.get_ccx(0); collect_translation_items(&ccx); // Translate all items. See `TransModVisitor` for @@ -2743,7 +2743,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, symbol_names_test::report_symbol_names(&ccx); } - for ccx in shared_ccx.iter() { + for ccx in crate_context_list.iter() { if ccx.sess().opts.debuginfo != NoDebugInfo { debuginfo::finalize(&ccx); } @@ -2792,7 +2792,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, } } - let modules = shared_ccx.iter() + let modules = crate_context_list.iter() .map(|ccx| ModuleTranslation { llcx: ccx.llcx(), llmod: ccx.llmod() }) .collect(); @@ -2819,13 +2819,13 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, } if codegen_units > 1 { - internalize_symbols(&shared_ccx, + internalize_symbols(&crate_context_list, &reachable_symbols.iter().map(|x| &x[..]).collect()); } if sess.target.target.options.is_like_msvc && sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib) { - create_imps(&shared_ccx); + create_imps(&crate_context_list); } let metadata_module = ModuleTranslation { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 2ee880fa3d850..7db42bb00ee1b 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -64,8 +64,6 @@ pub struct Stats { /// crate, so it must not contain references to any LLVM data structures /// (aside from metadata-related ones). pub struct SharedCrateContext<'a, 'tcx: 'a> { - local_ccxs: Vec>, - metadata_llmod: ModuleRef, metadata_llcx: ContextRef, @@ -95,7 +93,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { pub struct LocalCrateContext<'tcx> { llmod: ModuleRef, llcx: ContextRef, - tn: TypeNames, + tn: TypeNames, // FIXME: This seems to be largely unused. needs_unwind_cleanup_cache: RefCell, bool>>, fn_pointer_shims: RefCell, ValueRef>>, drop_glues: RefCell, ValueRef>>, @@ -191,16 +189,65 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> { } } +pub struct CrateContextList<'a, 'tcx: 'a> { + shared: &'a SharedCrateContext<'a, 'tcx>, + local_ccxs: Vec>, +} + +impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { + + pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>, + local_count: usize) + -> CrateContextList<'a, 'tcx> { + CrateContextList { + shared: shared_ccx, + local_ccxs: (0..local_count).map(|index| { + // Append ".rs" to crate name as LLVM module identifier. + // + // LLVM code generator emits a ".file filename" directive + // for ELF backends. Value of the "filename" is set as the + // LLVM module identifier. Due to a LLVM MC bug[1], LLVM + // crashes if the module identifier is same as other symbols + // such as a function name in the module. + // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 + let llmod_id = format!("{}.{}.rs", shared_ccx.link_meta.crate_name, index); + LocalCrateContext::new(shared_ccx, &llmod_id[..]) + }).collect() + } + } + + pub fn iter<'b>(&'b self) -> CrateContextIterator<'b, 'tcx> { + CrateContextIterator { + shared: self.shared, + index: 0, + local_ccxs: &self.local_ccxs[..] + } + } + + pub fn get_ccx<'b>(&'b self, index: usize) -> CrateContext<'b, 'tcx> { + CrateContext { + shared: self.shared, + index: index, + local_ccxs: &self.local_ccxs[..], + } + } + + pub fn shared(&self) -> &'a SharedCrateContext<'a, 'tcx> { + self.shared + } +} + pub struct CrateContext<'a, 'tcx: 'a> { shared: &'a SharedCrateContext<'a, 'tcx>, - local: &'a LocalCrateContext<'tcx>, - /// The index of `local` in `shared.local_ccxs`. This is used in + local_ccxs: &'a [LocalCrateContext<'tcx>], + /// The index of `local` in `local_ccxs`. This is used in /// `maybe_iter(true)` to identify the original `LocalCrateContext`. index: usize, } pub struct CrateContextIterator<'a, 'tcx: 'a> { shared: &'a SharedCrateContext<'a, 'tcx>, + local_ccxs: &'a [LocalCrateContext<'tcx>], index: usize, } @@ -208,7 +255,7 @@ impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> { type Item = CrateContext<'a, 'tcx>; fn next(&mut self) -> Option> { - if self.index >= self.shared.local_ccxs.len() { + if self.index >= self.local_ccxs.len() { return None; } @@ -217,8 +264,8 @@ impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> { Some(CrateContext { shared: self.shared, - local: &self.shared.local_ccxs[index], index: index, + local_ccxs: self.local_ccxs, }) } } @@ -226,6 +273,7 @@ impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> { /// The iterator produced by `CrateContext::maybe_iter`. pub struct CrateContextMaybeIterator<'a, 'tcx: 'a> { shared: &'a SharedCrateContext<'a, 'tcx>, + local_ccxs: &'a [LocalCrateContext<'tcx>], index: usize, single: bool, origin: usize, @@ -235,20 +283,20 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> { type Item = (CrateContext<'a, 'tcx>, bool); fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> { - if self.index >= self.shared.local_ccxs.len() { + if self.index >= self.local_ccxs.len() { return None; } let index = self.index; self.index += 1; if self.single { - self.index = self.shared.local_ccxs.len(); + self.index = self.local_ccxs.len(); } let ccx = CrateContext { shared: self.shared, - local: &self.shared.local_ccxs[index], index: index, + local_ccxs: self.local_ccxs }; Some((ccx, index == self.origin)) } @@ -288,9 +336,7 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR } impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { - pub fn new(crate_name: &str, - local_count: usize, - tcx: &'b TyCtxt<'tcx>, + pub fn new(tcx: &'b TyCtxt<'tcx>, mir_map: &'b MirMap<'tcx>, export_map: ExportMap, symbol_hasher: Sha256, @@ -348,8 +394,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { // start) and then strongly recommending static linkage on MSVC! let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc; - let mut shared_ccx = SharedCrateContext { - local_ccxs: Vec::with_capacity(local_count), + SharedCrateContext { metadata_llmod: metadata_llmod, metadata_llcx: metadata_llcx, export_map: export_map, @@ -378,55 +423,9 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { available_drop_glues: RefCell::new(FnvHashMap()), use_dll_storage_attrs: use_dll_storage_attrs, translation_items: RefCell::new(FnvHashMap()), - }; - - for i in 0..local_count { - // Append ".rs" to crate name as LLVM module identifier. - // - // LLVM code generator emits a ".file filename" directive - // for ELF backends. Value of the "filename" is set as the - // LLVM module identifier. Due to a LLVM MC bug[1], LLVM - // crashes if the module identifier is same as other symbols - // such as a function name in the module. - // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 - let llmod_id = format!("{}.{}.rs", crate_name, i); - let local_ccx = LocalCrateContext::new(&shared_ccx, &llmod_id[..]); - shared_ccx.local_ccxs.push(local_ccx); } - - shared_ccx } - pub fn iter<'a>(&'a self) -> CrateContextIterator<'a, 'tcx> { - CrateContextIterator { - shared: self, - index: 0, - } - } - - pub fn get_ccx<'a>(&'a self, index: usize) -> CrateContext<'a, 'tcx> { - CrateContext { - shared: self, - local: &self.local_ccxs[index], - index: index, - } - } - - fn get_smallest_ccx<'a>(&'a self) -> CrateContext<'a, 'tcx> { - let (local_ccx, index) = - self.local_ccxs - .iter() - .zip(0..self.local_ccxs.len()) - .min_by_key(|&(local_ccx, _idx)| local_ccx.n_llvm_insns.get()) - .unwrap(); - CrateContext { - shared: self, - local: local_ccx, - index: index, - } - } - - pub fn metadata_llmod(&self) -> ModuleRef { self.metadata_llmod } @@ -481,7 +480,7 @@ impl<'tcx> LocalCrateContext<'tcx> { None }; - let mut local_ccx = LocalCrateContext { + let local_ccx = LocalCrateContext { llmod: llmod, llcx: llcx, tn: TypeNames::new(), @@ -522,21 +521,28 @@ impl<'tcx> LocalCrateContext<'tcx> { .clone())), }; - local_ccx.int_type = Type::int(&local_ccx.dummy_ccx(shared)); - local_ccx.opaque_vec_type = Type::opaque_vec(&local_ccx.dummy_ccx(shared)); - - // Done mutating local_ccx directly. (The rest of the - // initialization goes through RefCell.) - { - let ccx = local_ccx.dummy_ccx(shared); + let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = { + // Do a little dance to create a dummy CrateContext, so we can + // create some things in the LLVM module of this codegen unit + let mut local_ccxs = vec![local_ccx]; + let (int_type, opaque_vec_type, str_slice_ty) = { + let dummy_ccx = LocalCrateContext::dummy_ccx(shared, + local_ccxs.as_mut_slice()); + let mut str_slice_ty = Type::named_struct(&dummy_ccx, "str_slice"); + str_slice_ty.set_struct_body(&[Type::i8p(&dummy_ccx), + Type::int(&dummy_ccx)], + false); + (Type::int(&dummy_ccx), Type::opaque_vec(&dummy_ccx), str_slice_ty) + }; + (int_type, opaque_vec_type, str_slice_ty, local_ccxs.pop().unwrap()) + }; - let mut str_slice_ty = Type::named_struct(&ccx, "str_slice"); - str_slice_ty.set_struct_body(&[Type::i8p(&ccx), ccx.int_type()], false); - ccx.tn().associate_type("str_slice", &str_slice_ty); + local_ccx.int_type = int_type; + local_ccx.opaque_vec_type = opaque_vec_type; + local_ccx.tn.associate_type("str_slice", &str_slice_ty); - if ccx.sess().count_llvm_insns() { - base::init_insn_ctxt() - } + if shared.tcx.sess.count_llvm_insns() { + base::init_insn_ctxt() } local_ccx @@ -545,18 +551,19 @@ impl<'tcx> LocalCrateContext<'tcx> { /// Create a dummy `CrateContext` from `self` and the provided /// `SharedCrateContext`. This is somewhat dangerous because `self` may - /// not actually be an element of `shared.local_ccxs`, which can cause some - /// operations to panic unexpectedly. + /// not be fully initialized. /// /// This is used in the `LocalCrateContext` constructor to allow calling /// functions that expect a complete `CrateContext`, even before the local /// portion is fully initialized and attached to the `SharedCrateContext`. - fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext<'a, 'tcx>) + fn dummy_ccx<'a>(shared: &'a SharedCrateContext<'a, 'tcx>, + local_ccxs: &'a [LocalCrateContext<'tcx>]) -> CrateContext<'a, 'tcx> { + assert!(local_ccxs.len() == 1); CrateContext { shared: shared, - local: self, - index: !0 as usize, + index: 0, + local_ccxs: local_ccxs } } } @@ -567,13 +574,23 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn local(&self) -> &'b LocalCrateContext<'tcx> { - self.local + &self.local_ccxs[self.index] } /// Get a (possibly) different `CrateContext` from the same /// `SharedCrateContext`. - pub fn rotate(&self) -> CrateContext<'b, 'tcx> { - self.shared.get_smallest_ccx() + pub fn rotate(&'b self) -> CrateContext<'b, 'tcx> { + let (_, index) = + self.local_ccxs + .iter() + .zip(0..self.local_ccxs.len()) + .min_by_key(|&(local_ccx, _idx)| local_ccx.n_llvm_insns.get()) + .unwrap(); + CrateContext { + shared: self.shared, + index: index, + local_ccxs: &self.local_ccxs[..], + } } /// Either iterate over only `self`, or iterate over all `CrateContext`s in @@ -588,10 +605,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { index: if iter_all { 0 } else { self.index }, single: !iter_all, origin: self.index, + local_ccxs: self.local_ccxs, } } - pub fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx> { self.shared.tcx } @@ -605,7 +622,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn raw_builder<'a>(&'a self) -> BuilderRef { - self.local.builder.b + self.local().builder.b } pub fn get_intrinsic(&self, key: &str) -> ValueRef { @@ -619,11 +636,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn llmod(&self) -> ModuleRef { - self.local.llmod + self.local().llmod } pub fn llcx(&self) -> ContextRef { - self.local.llcx + self.local().llcx } pub fn td(&self) -> llvm::TargetDataRef { @@ -631,7 +648,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn tn<'a>(&'a self) -> &'a TypeNames { - &self.local.tn + &self.local().tn } pub fn export_map<'a>(&'a self) -> &'a ExportMap { @@ -651,56 +668,56 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn needs_unwind_cleanup_cache(&self) -> &RefCell, bool>> { - &self.local.needs_unwind_cleanup_cache + &self.local().needs_unwind_cleanup_cache } pub fn fn_pointer_shims(&self) -> &RefCell, ValueRef>> { - &self.local.fn_pointer_shims + &self.local().fn_pointer_shims } pub fn drop_glues<'a>(&'a self) -> &'a RefCell, ValueRef>> { - &self.local.drop_glues + &self.local().drop_glues } pub fn external<'a>(&'a self) -> &'a RefCell>> { - &self.local.external + &self.local().external } pub fn external_srcs<'a>(&'a self) -> &'a RefCell> { - &self.local.external_srcs + &self.local().external_srcs } pub fn instances<'a>(&'a self) -> &'a RefCell, ValueRef>> { - &self.local.instances + &self.local().instances } pub fn monomorphizing<'a>(&'a self) -> &'a RefCell> { - &self.local.monomorphizing + &self.local().monomorphizing } pub fn vtables<'a>(&'a self) -> &'a RefCell, ValueRef>> { - &self.local.vtables + &self.local().vtables } pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell> { - &self.local.const_cstr_cache + &self.local().const_cstr_cache } pub fn const_unsized<'a>(&'a self) -> &'a RefCell> { - &self.local.const_unsized + &self.local().const_unsized } pub fn const_globals<'a>(&'a self) -> &'a RefCell> { - &self.local.const_globals + &self.local().const_globals } pub fn const_values<'a>(&'a self) -> &'a RefCell), ValueRef>> { - &self.local.const_values + &self.local().const_values } pub fn extern_const_values<'a>(&'a self) -> &'a RefCell> { - &self.local.extern_const_values + &self.local().extern_const_values } pub fn statics<'a>(&'a self) -> &'a RefCell> { @@ -709,27 +726,27 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { pub fn impl_method_cache<'a>(&'a self) -> &'a RefCell> { - &self.local.impl_method_cache + &self.local().impl_method_cache } pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell> { - &self.local.closure_bare_wrapper_cache + &self.local().closure_bare_wrapper_cache } pub fn statics_to_rauw<'a>(&'a self) -> &'a RefCell> { - &self.local.statics_to_rauw + &self.local().statics_to_rauw } pub fn lltypes<'a>(&'a self) -> &'a RefCell, Type>> { - &self.local.lltypes + &self.local().lltypes } pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell, Type>> { - &self.local.llsizingtypes + &self.local().llsizingtypes } pub fn adt_reprs<'a>(&'a self) -> &'a RefCell, Rc>>> { - &self.local.adt_reprs + &self.local().adt_reprs } pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell { @@ -737,7 +754,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell, String>> { - &self.local.type_hashcodes + &self.local().type_hashcodes } pub fn stats<'a>(&'a self) -> &'a Stats { @@ -753,43 +770,43 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn int_type(&self) -> Type { - self.local.int_type + self.local().int_type } pub fn opaque_vec_type(&self) -> Type { - self.local.opaque_vec_type + self.local().opaque_vec_type } pub fn closure_vals<'a>(&'a self) -> &'a RefCell, ValueRef>> { - &self.local.closure_vals + &self.local().closure_vals } pub fn dbg_cx<'a>(&'a self) -> &'a Option> { - &self.local.dbg_cx + &self.local().dbg_cx } pub fn eh_personality<'a>(&'a self) -> &'a Cell> { - &self.local.eh_personality + &self.local().eh_personality } pub fn eh_unwind_resume<'a>(&'a self) -> &'a Cell> { - &self.local.eh_unwind_resume + &self.local().eh_unwind_resume } pub fn rust_try_fn<'a>(&'a self) -> &'a Cell> { - &self.local.rust_try_fn + &self.local().rust_try_fn } fn intrinsics<'a>(&'a self) -> &'a RefCell> { - &self.local.intrinsics + &self.local().intrinsics } pub fn count_llvm_insn(&self) { - self.local.n_llvm_insns.set(self.local.n_llvm_insns.get() + 1); + self.local().n_llvm_insns.set(self.local().n_llvm_insns.get() + 1); } pub fn trait_cache(&self) -> &RefCell>> { - &self.local.trait_cache + &self.local().trait_cache } pub fn obj_size_bound(&self) -> u64 { @@ -803,14 +820,14 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn enter_type_of(&self, ty: Ty<'tcx>) -> TypeOfDepthLock<'b, 'tcx> { - let current_depth = self.local.type_of_depth.get(); + let current_depth = self.local().type_of_depth.get(); debug!("enter_type_of({:?}) at depth {:?}", ty, current_depth); if current_depth > self.sess().recursion_limit.get() { self.sess().fatal( &format!("overflow representing the type `{}`", ty)) } - self.local.type_of_depth.set(current_depth + 1); - TypeOfDepthLock(self.local) + self.local().type_of_depth.set(current_depth + 1); + TypeOfDepthLock(self.local()) } pub fn check_overflow(&self) -> bool { From 60259b9d90d977659c19644260f729adc3e43d75 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 May 2016 14:24:41 -0400 Subject: [PATCH 02/16] Make trans::collector item printing methods independent of CrateContext. --- src/librustc_trans/base.rs | 2 +- src/librustc_trans/collector.rs | 128 ++++++++++++++++---------------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 98a84205930f8..bb5b1e5c77522 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -2964,7 +2964,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(ccx); + let mut output = i.to_string(ccx.tcx()); output.push_str(" @@"); let mut empty = Vec::new(); let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index a0311ec606627..cb94c2a2cce84 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -378,7 +378,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, // We've been here already, no need to search again. return; } - debug!("BEGIN collect_items_rec({})", starting_point.to_string(ccx)); + debug!("BEGIN collect_items_rec({})", starting_point.to_string(ccx.tcx())); let mut neighbors = Vec::new(); let recursion_depth_reset; @@ -430,7 +430,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, recursion_depths.insert(def_id, depth); } - debug!("END collect_items_rec({})", starting_point.to_string(ccx)); + debug!("END collect_items_rec({})", starting_point.to_string(ccx.tcx())); } fn record_references<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, @@ -657,7 +657,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } }; - debug!("find_drop_glue_neighbors: {}", type_to_string(ccx, ty)); + debug!("find_drop_glue_neighbors: {}", type_to_string(ccx.tcx(), ty)); // Make sure the exchange_free_fn() lang-item gets translated if // there is a boxed value. @@ -786,7 +786,7 @@ fn do_static_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, param_substs: &'tcx Substs<'tcx>) -> Option<(DefId, &'tcx Substs<'tcx>)> { debug!("do_static_dispatch(fn_def_id={}, fn_substs={:?}, param_substs={:?})", - def_id_to_string(ccx, fn_def_id), + def_id_to_string(ccx.tcx(), fn_def_id), fn_substs, param_substs); @@ -834,8 +834,8 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trait_id={}, \ callee_substs={:?}, \ param_substs={:?}", - def_id_to_string(ccx, trait_method.def_id), - def_id_to_string(ccx, trait_id), + def_id_to_string(ccx.tcx(), trait_method.def_id), + def_id_to_string(ccx.tcx(), trait_id), callee_substs, param_substs); @@ -968,7 +968,7 @@ fn create_fn_trans_item<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, -> TransItem<'tcx> { debug!("create_fn_trans_item(def_id={}, fn_substs={:?}, param_substs={:?})", - def_id_to_string(ccx, def_id), + def_id_to_string(ccx.tcx(), def_id), fn_substs, param_substs); @@ -1079,7 +1079,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { if self.mode == TransItemCollectionMode::Eager { debug!("RootCollector: ADT drop-glue for {}", - def_id_to_string(self.ccx, + def_id_to_string(self.ccx.tcx(), self.ccx.tcx().map.local_def_id(item.id))); let ty = glue::get_drop_glue_type(self.ccx, ty); @@ -1089,7 +1089,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { } hir::ItemStatic(..) => { debug!("RootCollector: ItemStatic({})", - def_id_to_string(self.ccx, + def_id_to_string(self.ccx.tcx(), self.ccx.tcx().map.local_def_id(item.id))); self.output.push(TransItem::Static(item.id)); } @@ -1099,7 +1099,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { let def_id = self.ccx.tcx().map.local_def_id(item.id); debug!("RootCollector: ItemFn({})", - def_id_to_string(self.ccx, def_id)); + def_id_to_string(self.ccx.tcx(), def_id)); let instance = Instance::mono(self.ccx.tcx(), def_id); self.output.push(TransItem::Fn(instance)); @@ -1136,7 +1136,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { let def_id = self.ccx.tcx().map.local_def_id(ii.id); debug!("RootCollector: MethodImplItem({})", - def_id_to_string(self.ccx, def_id)); + def_id_to_string(self.ccx.tcx(), def_id)); let instance = Instance::mono(self.ccx.tcx(), def_id); self.output.push(TransItem::Fn(instance)); @@ -1167,7 +1167,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let impl_def_id = tcx.map.local_def_id(item.id); debug!("create_trans_items_for_default_impls(item={})", - def_id_to_string(ccx, impl_def_id)); + def_id_to_string(ccx.tcx(), impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { let default_impls = tcx.provided_trait_methods(trait_ref.def_id); @@ -1229,9 +1229,9 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, /// Same as `unique_type_name()` but with the result pushed onto the given /// `output` parameter. -pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, - t: ty::Ty<'tcx>, - output: &mut String) { +pub fn push_unique_type_name<'tcx>(tcx: &TyCtxt<'tcx>, + t: ty::Ty<'tcx>, + output: &mut String) { match t.sty { ty::TyBool => output.push_str("bool"), ty::TyChar => output.push_str("char"), @@ -1250,13 +1250,13 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::TyFloat(ast::FloatTy::F64) => output.push_str("f64"), ty::TyStruct(adt_def, substs) | ty::TyEnum(adt_def, substs) => { - push_item_name(cx, adt_def.did, output); - push_type_params(cx, &substs.types, &[], output); + push_item_name(tcx, adt_def.did, output); + push_type_params(tcx, &substs.types, &[], output); }, ty::TyTuple(ref component_types) => { output.push('('); for &component_type in component_types { - push_unique_type_name(cx, component_type, output); + push_unique_type_name(tcx, component_type, output); output.push_str(", "); } if !component_types.is_empty() { @@ -1267,7 +1267,7 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }, ty::TyBox(inner_type) => { output.push_str("Box<"); - push_unique_type_name(cx, inner_type, output); + push_unique_type_name(tcx, inner_type, output); output.push('>'); }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { @@ -1277,7 +1277,7 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, hir::MutMutable => output.push_str("mut "), } - push_unique_type_name(cx, inner_type, output); + push_unique_type_name(tcx, inner_type, output); }, ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { output.push('&'); @@ -1285,22 +1285,22 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("mut "); } - push_unique_type_name(cx, inner_type, output); + push_unique_type_name(tcx, inner_type, output); }, ty::TyArray(inner_type, len) => { output.push('['); - push_unique_type_name(cx, inner_type, output); + push_unique_type_name(tcx, inner_type, output); output.push_str(&format!("; {}", len)); output.push(']'); }, ty::TySlice(inner_type) => { output.push('['); - push_unique_type_name(cx, inner_type, output); + push_unique_type_name(tcx, inner_type, output); output.push(']'); }, ty::TyTrait(ref trait_data) => { - push_item_name(cx, trait_data.principal.skip_binder().def_id, output); - push_type_params(cx, + push_item_name(tcx, trait_data.principal.skip_binder().def_id, output); + push_type_params(tcx, &trait_data.principal.skip_binder().substs.types, &trait_data.bounds.projection_bounds, output); @@ -1319,10 +1319,10 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("fn("); - let sig = cx.tcx().erase_late_bound_regions(sig); + let sig = tcx.erase_late_bound_regions(sig); if !sig.inputs.is_empty() { for ¶meter_type in &sig.inputs { - push_unique_type_name(cx, parameter_type, output); + push_unique_type_name(tcx, parameter_type, output); output.push_str(", "); } output.pop(); @@ -1343,7 +1343,7 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::FnConverging(result_type) if result_type.is_nil() => {} ty::FnConverging(result_type) => { output.push_str(" -> "); - push_unique_type_name(cx, result_type, output); + push_unique_type_name(tcx, result_type, output); } ty::FnDiverging => { output.push_str(" -> !"); @@ -1351,11 +1351,11 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }, ty::TyClosure(def_id, ref closure_substs) => { - push_item_name(cx, def_id, output); + push_item_name(tcx, def_id, output); output.push_str("{"); output.push_str(&format!("{}:{}", def_id.krate, def_id.index.as_usize())); output.push_str("}"); - push_type_params(cx, &closure_substs.func_substs.types, &[], output); + push_type_params(tcx, &closure_substs.func_substs.types, &[], output); } ty::TyError | ty::TyInfer(_) | @@ -1367,17 +1367,17 @@ pub fn push_unique_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } -fn push_item_name(ccx: &CrateContext, +fn push_item_name(tcx: &TyCtxt, def_id: DefId, output: &mut String) { - let def_path = ccx.tcx().def_path(def_id); + let def_path = tcx.def_path(def_id); // some_crate:: - output.push_str(&ccx.tcx().crate_name(def_path.krate)); + output.push_str(&tcx.crate_name(def_path.krate)); output.push_str("::"); // foo::bar::ItemName:: - for part in ccx.tcx().def_path(def_id).data { + for part in tcx.def_path(def_id).data { output.push_str(&format!("{}[{}]::", part.data.as_interned_str(), part.disambiguator)); @@ -1388,10 +1388,10 @@ fn push_item_name(ccx: &CrateContext, output.pop(); } -fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, - types: &'tcx subst::VecPerParamSpace>, - projections: &[ty::PolyProjectionPredicate<'tcx>], - output: &mut String) { +fn push_type_params<'tcx>(tcx: &TyCtxt<'tcx>, + types: &'tcx subst::VecPerParamSpace>, + projections: &[ty::PolyProjectionPredicate<'tcx>], + output: &mut String) { if types.is_empty() && projections.is_empty() { return; } @@ -1399,7 +1399,7 @@ fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push('<'); for &type_parameter in types { - push_unique_type_name(cx, type_parameter, output); + push_unique_type_name(tcx, type_parameter, output); output.push_str(", "); } @@ -1408,7 +1408,7 @@ fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let name = token::get_ident_interner().get(projection.projection_ty.item_name); output.push_str(&name[..]); output.push_str("="); - push_unique_type_name(cx, projection.ty, output); + push_unique_type_name(tcx, projection.ty, output); output.push_str(", "); } @@ -1418,24 +1418,24 @@ fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push('>'); } -fn push_instance_as_string<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - instance: Instance<'tcx>, - output: &mut String) { - push_item_name(ccx, instance.def, output); - push_type_params(ccx, &instance.substs.types, &[], output); +fn push_instance_as_string<'tcx>(tcx: &TyCtxt<'tcx>, + instance: Instance<'tcx>, + output: &mut String) { + push_item_name(tcx, instance.def, output); + push_type_params(tcx, &instance.substs.types, &[], output); } -pub fn def_id_to_string(ccx: &CrateContext, def_id: DefId) -> String { +pub fn def_id_to_string(tcx: &TyCtxt, def_id: DefId) -> String { let mut output = String::new(); - push_item_name(ccx, def_id, &mut output); + push_item_name(tcx, def_id, &mut output); output } -fn type_to_string<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - ty: ty::Ty<'tcx>) - -> String { +fn type_to_string<'tcx>(tcx: &TyCtxt<'tcx>, + ty: ty::Ty<'tcx>) + -> String { let mut output = String::new(); - push_unique_type_name(ccx, ty, &mut output); + push_unique_type_name(tcx, ty, &mut output); output } @@ -1492,8 +1492,8 @@ impl<'tcx> TransItem<'tcx> { } } - pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String { - let hir_map = &ccx.tcx().map; + pub fn to_string(&self, tcx: &TyCtxt<'tcx>) -> String { + let hir_map = &tcx.map; return match *self { TransItem::DropGlue(dg) => { @@ -1502,26 +1502,26 @@ impl<'tcx> TransItem<'tcx> { DropGlueKind::Ty(_) => s.push_str("drop-glue "), DropGlueKind::TyContents(_) => s.push_str("drop-glue-contents "), }; - push_unique_type_name(ccx, dg.ty(), &mut s); + push_unique_type_name(tcx, dg.ty(), &mut s); s } TransItem::Fn(instance) => { - to_string_internal(ccx, "fn ", instance) + to_string_internal(tcx, "fn ", instance) }, TransItem::Static(node_id) => { let def_id = hir_map.local_def_id(node_id); - let instance = Instance::mono(ccx.tcx(), def_id); - to_string_internal(ccx, "static ", instance) + let instance = Instance::mono(tcx, def_id); + to_string_internal(tcx, "static ", instance) }, }; - fn to_string_internal<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - prefix: &str, - instance: Instance<'tcx>) - -> String { + fn to_string_internal<'tcx>(tcx: &TyCtxt<'tcx>, + prefix: &str, + instance: Instance<'tcx>) + -> String { let mut result = String::with_capacity(32); result.push_str(prefix); - push_instance_as_string(ccx, instance, &mut result); + push_instance_as_string(tcx, instance, &mut result); result } } @@ -1575,7 +1575,7 @@ pub fn print_collection_results<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { let mut item_keys = FnvHashMap(); for (item, item_state) in trans_items.iter() { - let k = item.to_string(&ccx); + let k = item.to_string(ccx.tcx()); if item_keys.contains_key(&k) { let prev: (TransItem, TransItemState) = item_keys[&k]; @@ -1603,7 +1603,7 @@ pub fn print_collection_results<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { let mut generated = FnvHashSet(); for (item, item_state) in trans_items.iter() { - let item_key = item.to_string(&ccx); + let item_key = item.to_string(ccx.tcx()); match *item_state { TransItemState::PredictedAndGenerated => { From 100a4f5699eda98ad642adfb390cc8b8365c8aae Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 May 2016 14:29:02 -0400 Subject: [PATCH 03/16] trans: Make normalize_and_test_predicates() not depend on CrateContext. --- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/common.rs | 7 +++---- src/librustc_trans/meth.rs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index cb94c2a2cce84..e27dd335e6f72 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -1194,7 +1194,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(mth.is_provided); let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs); - if !normalize_and_test_predicates(ccx, predicates.into_vec()) { + if !normalize_and_test_predicates(ccx.tcx(), predicates.into_vec()) { continue; } diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 70348cf35e5f5..0684355cb1069 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -1129,14 +1129,13 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, /// returns false, then either normalize encountered an error or one /// of the predicates did not hold. Used when creating vtables to /// check for unsatisfiable methods. -pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - predicates: Vec>) - -> bool +pub fn normalize_and_test_predicates<'tcx>(tcx: &TyCtxt<'tcx>, + predicates: Vec>) + -> bool { debug!("normalize_and_test_predicates(predicates={:?})", predicates); - let tcx = ccx.tcx(); let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables, ProjectionMode::Any); let mut selcx = SelectionContext::new(&infcx); let mut fulfill_cx = traits::FulfillmentContext::new(); diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 9e5476ae80d47..b351394950b5e 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -287,7 +287,7 @@ pub fn get_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // try and trans it, in that case. Issue #23435. if mth.is_provided { let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs); - if !normalize_and_test_predicates(ccx, predicates.into_vec()) { + if !normalize_and_test_predicates(tcx, predicates.into_vec()) { debug!("get_vtable_methods: predicates do not hold"); return None; } From 2564199d8f50e1f6e5c915bf258999354c6f1262 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 May 2016 14:32:59 -0400 Subject: [PATCH 04/16] trans: Make meth::get_vtable_methods() not depend on CrateContext. --- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/meth.rs | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index e27dd335e6f72..a431ecd6d708d 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -1008,7 +1008,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, impl_def_id, substs, nested: _ }) => { - let items = meth::get_vtable_methods(ccx, impl_def_id, substs) + let items = meth::get_vtable_methods(ccx.tcx(), impl_def_id, substs) .into_iter() // filter out None values .filter_map(|opt_impl_method| opt_impl_method) diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index b351394950b5e..d08c26783e985 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -157,7 +157,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, substs, nested: _ }) => { let nullptr = C_null(Type::nil(ccx).ptr_to()); - get_vtable_methods(ccx, id, substs) + get_vtable_methods(tcx, id, substs) .into_iter() .map(|opt_mth| opt_mth.map_or(nullptr, |mth| { Callee::def(ccx, mth.method.def_id, &mth.substs).reify(ccx).val @@ -215,13 +215,11 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, vtable } -pub fn get_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - impl_id: DefId, - substs: &'tcx subst::Substs<'tcx>) - -> Vec>> +pub fn get_vtable_methods<'tcx>(tcx: &TyCtxt<'tcx>, + impl_id: DefId, + substs: &'tcx subst::Substs<'tcx>) + -> Vec>> { - let tcx = ccx.tcx(); - debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs); let trt_id = match tcx.impl_trait_ref(impl_id) { From d24ead0f93799c7c6646739396daf68ac46d7309 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 May 2016 14:59:16 -0400 Subject: [PATCH 05/16] trans: Make various trans::collector functions independent of CrateContext. --- src/librustc_trans/collector.rs | 101 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 52 deletions(-) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index a431ecd6d708d..2fb8c9737fa21 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -397,7 +397,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, } TransItem::Fn(instance) => { // Keep track of the monomorphization recursion depth - recursion_depth_reset = Some(check_recursion_limit(ccx, + recursion_depth_reset = Some(check_recursion_limit(ccx.tcx(), instance, recursion_depths)); @@ -420,7 +420,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, } } - record_references(ccx, starting_point, &neighbors[..], reference_map); + record_references(ccx.tcx(), starting_point, &neighbors[..], reference_map); for neighbour in neighbors { collect_items_rec(ccx, neighbour, visited, recursion_depths, reference_map); @@ -433,23 +433,23 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, debug!("END collect_items_rec({})", starting_point.to_string(ccx.tcx())); } -fn record_references<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - caller: TransItem<'tcx>, - callees: &[TransItem<'tcx>], - reference_map: &mut ReferenceMap<'tcx>) { +fn record_references<'tcx>(tcx: &TyCtxt<'tcx>, + caller: TransItem<'tcx>, + callees: &[TransItem<'tcx>], + reference_map: &mut ReferenceMap<'tcx>) { let iter = callees.into_iter() .map(|callee| { let is_inlining_candidate = callee.is_from_extern_crate() || - callee.requests_inline(ccx.tcx()); + callee.requests_inline(tcx); (*callee, is_inlining_candidate) }); reference_map.record_references(caller, iter); } -fn check_recursion_limit<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, - instance: Instance<'tcx>, - recursion_depths: &mut DefIdMap) - -> (DefId, usize) { +fn check_recursion_limit<'tcx>(tcx: &TyCtxt<'tcx>, + instance: Instance<'tcx>, + recursion_depths: &mut DefIdMap) + -> (DefId, usize) { let recursion_depth = recursion_depths.get(&instance.def) .map(|x| *x) .unwrap_or(0); @@ -458,13 +458,13 @@ fn check_recursion_limit<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, // Code that needs to instantiate the same function recursively // more than the recursion limit is assumed to be causing an // infinite expansion. - if recursion_depth > ccx.sess().recursion_limit.get() { + if recursion_depth > tcx.sess.recursion_limit.get() { let error = format!("reached the recursion limit while instantiating `{}`", instance); - if let Some(node_id) = ccx.tcx().map.as_local_node_id(instance.def) { - ccx.sess().span_fatal(ccx.tcx().map.span(node_id), &error); + if let Some(node_id) = tcx.map.as_local_node_id(instance.def) { + tcx.sess.span_fatal(tcx.map.span(node_id), &error); } else { - ccx.sess().fatal(&error); + tcx.sess.fatal(&error); } } @@ -488,8 +488,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match *rvalue { mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id, ref substs), _) => { - assert!(can_have_local_instance(self.ccx, def_id)); - let trans_item = create_fn_trans_item(self.ccx, + assert!(can_have_local_instance(self.ccx.tcx(), def_id)); + let trans_item = create_fn_trans_item(self.ccx.tcx(), def_id, substs.func_substs, self.param_substs); @@ -527,9 +527,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { .require(ExchangeMallocFnLangItem) .unwrap_or_else(|e| self.ccx.sess().fatal(&e)); - assert!(can_have_local_instance(self.ccx, exchange_malloc_fn_def_id)); + assert!(can_have_local_instance(self.ccx.tcx(), exchange_malloc_fn_def_id)); let exchange_malloc_fn_trans_item = - create_fn_trans_item(self.ccx, + create_fn_trans_item(self.ccx.tcx(), exchange_malloc_fn_def_id, &Substs::empty(), self.param_substs); @@ -596,7 +596,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // result in a translation item ... if can_result_in_trans_item(self.ccx, callee_def_id) { // ... and create one if it does. - let trans_item = create_fn_trans_item(self.ccx, + let trans_item = create_fn_trans_item(self.ccx.tcx(), callee_def_id, callee_substs, self.param_substs); @@ -631,18 +631,18 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { return false; } - can_have_local_instance(ccx, def_id) + can_have_local_instance(ccx.tcx(), def_id) } } } -fn can_have_local_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - def_id: DefId) - -> bool { +fn can_have_local_instance<'tcx>(tcx: &TyCtxt<'tcx>, + def_id: DefId) + -> bool { // Take a look if we have the definition available. If not, we // will not emit code for this item in the local crate, and thus // don't create a translation item for it. - def_id.is_local() || ccx.sess().cstore.is_item_mir_available(def_id) + def_id.is_local() || tcx.sess.cstore.is_item_mir_available(def_id) } fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, @@ -667,9 +667,9 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .require(ExchangeFreeFnLangItem) .unwrap_or_else(|e| ccx.sess().fatal(&e)); - assert!(can_have_local_instance(ccx, exchange_free_fn_def_id)); + assert!(can_have_local_instance(ccx.tcx(), exchange_free_fn_def_id)); let exchange_free_fn_trans_item = - create_fn_trans_item(ccx, + create_fn_trans_item(ccx.tcx(), exchange_free_fn_def_id, &Substs::empty(), &Substs::empty()); @@ -706,8 +706,8 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => bug!() }; - if can_have_local_instance(ccx, destructor_did) { - let trans_item = create_fn_trans_item(ccx, + if can_have_local_instance(ccx.tcx(), destructor_did) { + let trans_item = create_fn_trans_item(ccx.tcx(), destructor_did, substs, &Substs::empty()); @@ -961,29 +961,27 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -fn create_fn_trans_item<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - def_id: DefId, - fn_substs: &Substs<'tcx>, - param_substs: &Substs<'tcx>) - -> TransItem<'tcx> -{ +fn create_fn_trans_item<'tcx>(tcx: &TyCtxt<'tcx>, + def_id: DefId, + fn_substs: &Substs<'tcx>, + param_substs: &Substs<'tcx>) + -> TransItem<'tcx> { debug!("create_fn_trans_item(def_id={}, fn_substs={:?}, param_substs={:?})", - def_id_to_string(ccx.tcx(), def_id), + def_id_to_string(tcx, def_id), fn_substs, param_substs); // We only get here, if fn_def_id either designates a local item or // an inlineable external item. Non-inlineable external items are // ignored because we don't want to generate any code for them. - let concrete_substs = monomorphize::apply_param_substs(ccx.tcx(), + let concrete_substs = monomorphize::apply_param_substs(tcx, param_substs, fn_substs); - let concrete_substs = ccx.tcx().erase_regions(&concrete_substs); + let concrete_substs = tcx.erase_regions(&concrete_substs); let trans_item = TransItem::Fn(Instance::new(def_id, - &ccx.tcx().mk_substs(concrete_substs))); - + &tcx.mk_substs(concrete_substs))); return trans_item; } @@ -1014,8 +1012,8 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .filter_map(|opt_impl_method| opt_impl_method) // create translation items .filter_map(|impl_method| { - if can_have_local_instance(ccx, impl_method.method.def_id) { - Some(create_fn_trans_item(ccx, + if can_have_local_instance(ccx.tcx(), impl_method.method.def_id) { + Some(create_fn_trans_item(ccx.tcx(), impl_method.method.def_id, &impl_method.substs, &Substs::empty())) @@ -1063,7 +1061,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemImpl(..) => { if self.mode == TransItemCollectionMode::Eager { - create_trans_items_for_default_impls(self.ccx, + create_trans_items_for_default_impls(self.ccx.tcx(), item, self.output); } @@ -1149,9 +1147,9 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { } } -fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - item: &'tcx hir::Item, - output: &mut Vec>) { +fn create_trans_items_for_default_impls<'tcx>(tcx: &TyCtxt<'tcx>, + item: &'tcx hir::Item, + output: &mut Vec>) { match item.node { hir::ItemImpl(_, _, @@ -1163,11 +1161,10 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, return } - let tcx = ccx.tcx(); let impl_def_id = tcx.map.local_def_id(item.id); debug!("create_trans_items_for_default_impls(item={})", - def_id_to_string(ccx.tcx(), impl_def_id)); + def_id_to_string(tcx, impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { let default_impls = tcx.provided_trait_methods(trait_ref.def_id); @@ -1194,13 +1191,13 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(mth.is_provided); let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs); - if !normalize_and_test_predicates(ccx.tcx(), predicates.into_vec()) { + if !normalize_and_test_predicates(tcx, predicates.into_vec()) { continue; } - if can_have_local_instance(ccx, default_impl.def_id) { - let empty_substs = ccx.tcx().mk_substs(ccx.tcx().erase_regions(mth.substs)); - let item = create_fn_trans_item(ccx, + if can_have_local_instance(tcx, default_impl.def_id) { + let empty_substs = tcx.mk_substs(tcx.erase_regions(mth.substs)); + let item = create_fn_trans_item(tcx, default_impl.def_id, callee_substs, empty_substs); From 566aa54b494524e4af48fd0d72cada6ebf138487 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 00:47:28 -0400 Subject: [PATCH 06/16] trans: Make common::fulfill_obligation only depend on SharedCrateContext. Plus make it produce a nicer dependency graph via DepTrackingMap::memoize(). --- src/librustc_trans/base.rs | 2 +- src/librustc_trans/callee.rs | 2 +- src/librustc_trans/collector.rs | 6 +- src/librustc_trans/common.rs | 118 +++++++++++++++----------------- src/librustc_trans/context.rs | 15 ++-- src/librustc_trans/glue.rs | 2 +- src/librustc_trans/meth.rs | 2 +- 7 files changed, 70 insertions(+), 77 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index bb5b1e5c77522..098b7d163c196 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -678,7 +678,7 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, substs: ccx.tcx().mk_substs(trait_substs) }); - match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + match fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { ccx.tcx().custom_coerce_unsized_kind(impl_def_id) } diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index f5288220b2ea6..db605e4dc5d68 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -156,7 +156,7 @@ impl<'tcx> Callee<'tcx> { let trait_id = method_item.container().id(); let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id)); let trait_ref = infer::normalize_associated_type(tcx, &trait_ref); - match common::fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) { traits::VtableImpl(vtable_impl) => { let impl_did = vtable_impl.impl_def_id; let mname = tcx.item_name(def_id); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 2fb8c9737fa21..db0e04c347633 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -701,7 +701,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, substs: self_type_substs, }.to_poly_trait_ref(); - let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + let substs = match fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) { traits::VtableImpl(data) => data.substs, _ => bug!() }; @@ -844,7 +844,7 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, callee_substs); let trait_ref = ty::Binder(rcvr_substs.to_trait_ref(tcx, trait_id)); - let vtbl = fulfill_obligation(ccx, DUMMY_SP, trait_ref); + let vtbl = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); // Now that we know which impl is being used, we can dispatch to // the actual function: @@ -999,7 +999,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Walk all methods of the trait, including those of its supertraits for trait_ref in traits::supertraits(ccx.tcx(), poly_trait_ref) { - let vtable = fulfill_obligation(ccx, DUMMY_SP, trait_ref); + let vtable = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); match vtable { traits::VtableImpl( traits::VtableImplData { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 0684355cb1069..65d307cec688d 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -20,6 +20,7 @@ use rustc::cfg; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::infer; +use rustc::util::common::MemoizationMap; use middle::lang_items::LangItem; use rustc::ty::subst::Substs; use abi::{Abi, FnType}; @@ -54,7 +55,7 @@ use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::InternedString; use syntax::parse::token; -pub use context::CrateContext; +pub use context::{CrateContext, SharedCrateContext}; /// Is the type's representation size known at compile time? pub fn type_is_sized<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { @@ -1051,7 +1052,7 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should /// guarantee to us that all nested obligations *could be* resolved if we wanted to. -pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn fulfill_obligation<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, span: Span, trait_ref: ty::PolyTraitRef<'tcx>) -> traits::Vtable<'tcx, ()> @@ -1061,68 +1062,63 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Remove any references to regions; this helps improve caching. let trait_ref = tcx.erase_regions(&trait_ref); - // First check the cache. - match ccx.trait_cache().borrow().get(&trait_ref) { - Some(vtable) => { - info!("Cache hit: {:?}", trait_ref); - return (*vtable).clone(); - } - None => { } - } - - debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}", - trait_ref, trait_ref.def_id()); - - - // Do the initial selection for the obligation. This yields the - // shallow result we are looking for -- that is, what specific impl. - let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables, ProjectionMode::Any); - let mut selcx = SelectionContext::new(&infcx); - - let obligation = - traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID), - trait_ref.to_poly_trait_predicate()); - let selection = match selcx.select(&obligation) { - Ok(Some(selection)) => selection, - Ok(None) => { - // Ambiguity can happen when monomorphizing during trans - // expands to some humongo type that never occurred - // statically -- this humongo type can then overflow, - // leading to an ambiguous result. So report this as an - // overflow bug, since I believe this is the only case - // where ambiguity can result. - debug!("Encountered ambiguity selecting `{:?}` during trans, \ - presuming due to overflow", - trait_ref); - ccx.sess().span_fatal( - span, - "reached the recursion limit during monomorphization (selection ambiguity)"); - } - Err(e) => { - span_bug!( - span, - "Encountered error `{:?}` selecting `{:?}` during trans", - e, - trait_ref) - } - }; - - // Currently, we use a fulfillment context to completely resolve - // all nested obligations. This is because they can inform the - // inference of the impl's type parameters. - let mut fulfill_cx = traits::FulfillmentContext::new(); - let vtable = selection.map(|predicate| { - fulfill_cx.register_predicate_obligation(&infcx, predicate); - }); - let vtable = infer::drain_fulfillment_cx_or_panic( - span, &infcx, &mut fulfill_cx, &vtable - ); + ccx.trait_cache().memoize(trait_ref, || { + debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}", + trait_ref, trait_ref.def_id()); + + // Do the initial selection for the obligation. This yields the + // shallow result we are looking for -- that is, what specific impl. + let infcx = infer::normalizing_infer_ctxt(tcx, + &tcx.tables, + ProjectionMode::Any); + let mut selcx = SelectionContext::new(&infcx); + + let obligation_cause = traits::ObligationCause::misc(span, + ast::DUMMY_NODE_ID); + let obligation = traits::Obligation::new(obligation_cause, + trait_ref.to_poly_trait_predicate()); + + let selection = match selcx.select(&obligation) { + Ok(Some(selection)) => selection, + Ok(None) => { + // Ambiguity can happen when monomorphizing during trans + // expands to some humongo type that never occurred + // statically -- this humongo type can then overflow, + // leading to an ambiguous result. So report this as an + // overflow bug, since I believe this is the only case + // where ambiguity can result. + debug!("Encountered ambiguity selecting `{:?}` during trans, \ + presuming due to overflow", + trait_ref); + ccx.sess().span_fatal( + span, + "reached the recursion limit during monomorphization \ + (selection ambiguity)"); + } + Err(e) => { + span_bug!( + span, + "Encountered error `{:?}` selecting `{:?}` during trans", + e, + trait_ref) + } + }; - info!("Cache miss: {:?} => {:?}", trait_ref, vtable); + // Currently, we use a fulfillment context to completely resolve + // all nested obligations. This is because they can inform the + // inference of the impl's type parameters. + let mut fulfill_cx = traits::FulfillmentContext::new(); + let vtable = selection.map(|predicate| { + fulfill_cx.register_predicate_obligation(&infcx, predicate); + }); + let vtable = infer::drain_fulfillment_cx_or_panic( + span, &infcx, &mut fulfill_cx, &vtable + ); - ccx.trait_cache().borrow_mut().insert(trait_ref, vtable.clone()); + info!("Cache miss: {:?} => {:?}", trait_ref, vtable); - vtable + vtable + }) } /// Normalizes the predicates and checks whether they hold. If this diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 7db42bb00ee1b..d7ec448a7f0b2 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -84,6 +84,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { use_dll_storage_attrs: bool, translation_items: RefCell, TransItemState>>, + trait_cache: RefCell>>, } /// The local portion of a `CrateContext`. There is one `LocalCrateContext` @@ -169,8 +170,6 @@ pub struct LocalCrateContext<'tcx> { /// Depth of the current type-of computation - used to bail out type_of_depth: Cell, - - trait_cache: RefCell>>, } // Implement DepTrackingMapConfig for `trait_cache` @@ -423,6 +422,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { available_drop_glues: RefCell::new(FnvHashMap()), use_dll_storage_attrs: use_dll_storage_attrs, translation_items: RefCell::new(FnvHashMap()), + trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())), } } @@ -446,6 +446,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { &self.item_symbols } + pub fn trait_cache(&self) -> &RefCell>> { + &self.trait_cache + } + pub fn link_meta<'a>(&'a self) -> &'a LinkMeta { &self.link_meta } @@ -516,9 +520,6 @@ impl<'tcx> LocalCrateContext<'tcx> { intrinsics: RefCell::new(FnvHashMap()), n_llvm_insns: Cell::new(0), type_of_depth: Cell::new(0), - trait_cache: RefCell::new(DepTrackingMap::new(shared.tcx - .dep_graph - .clone())), }; let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = { @@ -805,10 +806,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local().n_llvm_insns.set(self.local().n_llvm_insns.get() + 1); } - pub fn trait_cache(&self) -> &RefCell>> { - &self.local().trait_cache - } - pub fn obj_size_bound(&self) -> u64 { self.tcx().data_layout.obj_size_bound() } diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 06761a7016add..06f9000c4ba90 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -364,7 +364,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, def_id: tcx.lang_items.drop_trait().unwrap(), substs: tcx.mk_substs(Substs::empty().with_self_ty(t)) }); - let vtbl = match fulfill_obligation(bcx.ccx(), DUMMY_SP, trait_ref) { + let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) { traits::VtableImpl(data) => data, _ => bug!("dtor for {:?} is not an impl???", t) }; diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index d08c26783e985..648a232ef6946 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -144,7 +144,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Not in the cache. Build it. let methods = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| { - let vtable = fulfill_obligation(ccx, DUMMY_SP, trait_ref.clone()); + let vtable = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref.clone()); match vtable { // Should default trait error here? traits::VtableDefaultImpl(_) | From 3f74c6afe0821778047ec46f29b815fc30f7ec1f Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 00:55:53 -0400 Subject: [PATCH 07/16] trans: Make base::custom_coerce_unsize_info only depend on SharedCrateContext. --- src/librustc_trans/base.rs | 4 ++-- src/librustc_trans/collector.rs | 5 ++--- src/librustc_trans/expr.rs | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 098b7d163c196..10fd4b00f3cbd 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } -pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, +pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &SharedCrateContext<'ccx, 'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> CustomCoerceUnsized { @@ -678,7 +678,7 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, substs: ccx.tcx().mk_substs(trait_substs) }); - match fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) { + match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { ccx.tcx().custom_coerce_unsized_kind(impl_def_id) } diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index db0e04c347633..5258bdf5d3c5b 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -211,8 +211,7 @@ use syntax::parse::token; use base::{custom_coerce_unsize_info, llvm_linkage_by_name}; use context::CrateContext; -use common::{fulfill_obligation, normalize_and_test_predicates, - type_is_sized}; +use common::{fulfill_obligation, normalize_and_test_predicates, type_is_sized}; use glue::{self, DropGlueKind}; use llvm; use meth; @@ -937,7 +936,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &ty::TyStruct(target_adt_def, target_substs)) => { assert_eq!(source_adt_def, target_adt_def); - let kind = custom_coerce_unsize_info(ccx, source_ty, target_ty); + let kind = custom_coerce_unsize_info(ccx.shared(), source_ty, target_ty); let coerce_index = match kind { CustomCoerceUnsized::Struct(i) => i diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index cd11ca586890c..edb3d167ddeb0 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -510,7 +510,9 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let source = unpack_datum!(bcx, source.to_ref_datum(bcx)); assert!(target.kind.is_by_ref()); - let kind = custom_coerce_unsize_info(bcx.ccx(), source.ty, target.ty); + let kind = custom_coerce_unsize_info(bcx.ccx().shared(), + source.ty, + target.ty); let repr_source = adt::represent_type(bcx.ccx(), source.ty); let src_fields = match &*repr_source { From 75bf6173e5f549a8345c092d4c2fe9ba896253e0 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 01:23:44 -0400 Subject: [PATCH 08/16] trans: Make glue::get_drop_glue_type() independent of CrateContext. --- src/librustc_trans/collector.rs | 14 +++++++------- src/librustc_trans/glue.rs | 26 ++++++++++++++------------ src/librustc_trans/mir/block.rs | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 5258bdf5d3c5b..ac42eb0ee623d 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -390,7 +390,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, TransItem::Static(node_id) => { let def_id = ccx.tcx().map.local_def_id(node_id); let ty = ccx.tcx().lookup_item_type(def_id).ty; - let ty = glue::get_drop_glue_type(ccx, ty); + let ty = glue::get_drop_glue_type(ccx.tcx(), ty); neighbors.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); recursion_depth_reset = None; } @@ -554,7 +554,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.param_substs, &ty); let ty = self.ccx.tcx().erase_regions(&ty); - let ty = glue::get_drop_glue_type(self.ccx, ty); + let ty = glue::get_drop_glue_type(self.ccx.tcx(), ty); self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); } @@ -740,7 +740,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let field_type = monomorphize::apply_param_substs(ccx.tcx(), substs, &field.unsubst_ty()); - let field_type = glue::get_drop_glue_type(ccx, field_type); + let field_type = glue::get_drop_glue_type(ccx.tcx(), field_type); if glue::type_needs_drop(ccx.tcx(), field_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(field_type))); @@ -749,7 +749,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } ty::TyClosure(_, ref substs) => { for upvar_ty in &substs.upvar_tys { - let upvar_ty = glue::get_drop_glue_type(ccx, upvar_ty); + let upvar_ty = glue::get_drop_glue_type(ccx.tcx(), upvar_ty); if glue::type_needs_drop(ccx.tcx(), upvar_ty) { output.push(TransItem::DropGlue(DropGlueKind::Ty(upvar_ty))); } @@ -757,14 +757,14 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } ty::TyBox(inner_type) | ty::TyArray(inner_type, _) => { - let inner_type = glue::get_drop_glue_type(ccx, inner_type); + let inner_type = glue::get_drop_glue_type(ccx.tcx(), inner_type); if glue::type_needs_drop(ccx.tcx(), inner_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type))); } } ty::TyTuple(ref args) => { for arg in args { - let arg = glue::get_drop_glue_type(ccx, arg); + let arg = glue::get_drop_glue_type(ccx.tcx(), arg); if glue::type_needs_drop(ccx.tcx(), arg) { output.push(TransItem::DropGlue(DropGlueKind::Ty(arg))); } @@ -1079,7 +1079,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { def_id_to_string(self.ccx.tcx(), self.ccx.tcx().map.local_def_id(item.id))); - let ty = glue::get_drop_glue_type(self.ccx, ty); + let ty = glue::get_drop_glue_type(self.ccx.tcx(), ty); self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); } } diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 06f9000c4ba90..e83580b95bcc4 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -19,7 +19,7 @@ use llvm; use llvm::{ValueRef, get_param}; use middle::lang_items::ExchangeFreeFnLangItem; use rustc::ty::subst::{Substs}; -use rustc::traits; +use rustc::{infer, traits}; use rustc::ty::{self, Ty, TyCtxt}; use abi::{Abi, FnType}; use adt; @@ -92,13 +92,12 @@ pub fn type_needs_drop<'tcx>(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { tcx.type_needs_drop_given_env(ty, &tcx.empty_parameter_environment()) } -pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - t: Ty<'tcx>) -> Ty<'tcx> { - let tcx = ccx.tcx(); +pub fn get_drop_glue_type<'tcx>(tcx: &TyCtxt<'tcx>, + t: Ty<'tcx>) -> Ty<'tcx> { // Even if there is no dtor for t, there might be one deeper down and we // might need to pass in the vtable ptr. if !type_is_sized(tcx, t) { - return ccx.tcx().erase_regions(&t); + return tcx.erase_regions(&t); } // FIXME (#22815): note that type_needs_drop conservatively @@ -116,15 +115,18 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, match t.sty { ty::TyBox(typ) if !type_needs_drop(&tcx, typ) && type_is_sized(tcx, typ) => { - let llty = sizing_type_of(ccx, typ); - // `Box` does not allocate. - if llsize_of_alloc(ccx, llty) == 0 { + let infcx = infer::normalizing_infer_ctxt(tcx, + &tcx.tables, + traits::ProjectionMode::Any); + let layout = t.layout(&infcx).unwrap(); + if layout.size(&tcx.data_layout).bytes() == 0 { + // `Box` does not allocate. tcx.types.i8 } else { - ccx.tcx().erase_regions(&t) + tcx.erase_regions(&t) } } - _ => ccx.tcx().erase_regions(&t) + _ => tcx.erase_regions(&t) } } @@ -154,7 +156,7 @@ pub fn drop_ty_core<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, DropGlueKind::Ty(t) }; let glue = get_drop_glue_core(ccx, g); - let glue_type = get_drop_glue_type(ccx, t); + let glue_type = get_drop_glue_type(ccx.tcx(), t); let ptr = if glue_type != t { PointerCast(bcx, v, type_of(ccx, glue_type).ptr_to()) } else { @@ -231,7 +233,7 @@ impl<'tcx> DropGlueKind<'tcx> { fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'tcx>) -> ValueRef { debug!("make drop glue for {:?}", g); - let g = g.map_ty(|t| get_drop_glue_type(ccx, t)); + let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t)); debug!("drop glue type {:?}", g); match ccx.drop_glues().borrow().get(&g) { Some(&glue) => return glue, diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index e605ef81c587f..39bf0da5cf957 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -136,7 +136,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { return; } let drop_fn = glue::get_drop_glue(bcx.ccx(), ty); - let drop_ty = glue::get_drop_glue_type(bcx.ccx(), ty); + let drop_ty = glue::get_drop_glue_type(bcx.tcx(), ty); let llvalue = if drop_ty != ty { bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to()) } else { From bb8c8c58d3d6db6af12b69d047b30c0277ef7263 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 13:33:14 -0400 Subject: [PATCH 09/16] Make trans::collector only depend on SharedCrateContext. --- src/librustc_trans/base.rs | 6 ++-- src/librustc_trans/collector.rs | 50 ++++++++++++++++----------------- src/librustc_trans/consts.rs | 2 +- src/librustc_trans/context.rs | 38 +++++++++++++++---------- src/librustc_trans/glue.rs | 2 +- 5 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 10fd4b00f3cbd..c89a8a930f727 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1824,7 +1824,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, closure_env: closure::ClosureEnv) { ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1); - if collector::collecting_debug_information(ccx) { + if collector::collecting_debug_information(ccx.shared()) { ccx.record_translation_item_as_generated(TransItem::Fn(instance)); } @@ -2738,7 +2738,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, krate.visit_all_items(&mut TransModVisitor { ccx: &ccx }); } - collector::print_collection_results(&ccx); + collector::print_collection_results(ccx.shared()); symbol_names_test::report_symbol_names(&ccx); } @@ -2934,7 +2934,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { }; let (items, reference_map) = time(time_passes, "translation item collection", || { - collector::collect_crate_translation_items(&ccx, collection_mode) + collector::collect_crate_translation_items(ccx.shared(), collection_mode) }); let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() { diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index ac42eb0ee623d..e815d7b61d7b1 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -210,7 +210,7 @@ use syntax::{attr, errors}; use syntax::parse::token; use base::{custom_coerce_unsize_info, llvm_linkage_by_name}; -use context::CrateContext; +use context::SharedCrateContext; use common::{fulfill_obligation, normalize_and_test_predicates, type_is_sized}; use glue::{self, DropGlueKind}; use llvm; @@ -319,7 +319,7 @@ impl<'tcx> ReferenceMap<'tcx> { } } -pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode) -> (FnvHashSet>, ReferenceMap<'tcx>) { @@ -347,7 +347,7 @@ pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Find all non-generic items by walking the HIR. These items serve as roots to // start monomorphizing from. -fn collect_roots<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn collect_roots<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode) -> Vec> { debug!("Collecting roots"); @@ -368,7 +368,7 @@ fn collect_roots<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } // Collect all monomorphized translation items reachable from `starting_point` -fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>, +fn collect_items_rec<'a, 'tcx: 'a>(ccx: &SharedCrateContext<'a, 'tcx>, starting_point: TransItem<'tcx>, visited: &mut FnvHashSet>, recursion_depths: &mut DefIdMap, @@ -473,7 +473,7 @@ fn check_recursion_limit<'tcx>(tcx: &TyCtxt<'tcx>, } struct MirNeighborCollector<'a, 'tcx: 'a> { - ccx: &'a CrateContext<'a, 'tcx>, + ccx: &'a SharedCrateContext<'a, 'tcx>, mir: &'a mir::Mir<'tcx>, output: &'a mut Vec>, param_substs: &'tcx Substs<'tcx> @@ -593,7 +593,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // object shim or a closure that is handled differently), // we check if the callee is something that will actually // result in a translation item ... - if can_result_in_trans_item(self.ccx, callee_def_id) { + if can_result_in_trans_item(self.ccx.tcx(), callee_def_id) { // ... and create one if it does. let trans_item = create_fn_trans_item(self.ccx.tcx(), callee_def_id, @@ -606,21 +606,21 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_operand(operand); - fn can_result_in_trans_item<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - def_id: DefId) - -> bool { - if !match ccx.tcx().lookup_item_type(def_id).ty.sty { + fn can_result_in_trans_item<'tcx>(tcx: &TyCtxt<'tcx>, + def_id: DefId) + -> bool { + if !match tcx.lookup_item_type(def_id).ty.sty { ty::TyFnDef(def_id, _, _) => { // Some constructors also have type TyFnDef but they are // always instantiated inline and don't result in // translation item. Same for FFI functions. - match ccx.tcx().map.get_if_local(def_id) { + match tcx.map.get_if_local(def_id) { Some(hir_map::NodeVariant(_)) | Some(hir_map::NodeStructCtor(_)) | Some(hir_map::NodeForeignItem(_)) => false, Some(_) => true, None => { - ccx.sess().cstore.variant_kind(def_id).is_none() + tcx.sess.cstore.variant_kind(def_id).is_none() } } } @@ -630,7 +630,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { return false; } - can_have_local_instance(ccx.tcx(), def_id) + can_have_local_instance(tcx, def_id) } } } @@ -644,7 +644,7 @@ fn can_have_local_instance<'tcx>(tcx: &TyCtxt<'tcx>, def_id.is_local() || tcx.sess.cstore.is_item_mir_available(def_id) } -fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, dg: DropGlueKind<'tcx>, output: &mut Vec>) { let ty = match dg { @@ -700,7 +700,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, substs: self_type_substs, }.to_poly_trait_ref(); - let substs = match fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) { + let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { traits::VtableImpl(data) => data.substs, _ => bug!() }; @@ -779,7 +779,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -fn do_static_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn do_static_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, fn_def_id: DefId, fn_substs: &'tcx Substs<'tcx>, param_substs: &'tcx Substs<'tcx>) @@ -822,7 +822,7 @@ fn do_static_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Given a trait-method and substitution information, find out the actual // implementation of the trait method. -fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, trait_method: &ty::Method, trait_id: DefId, callee_substs: &'tcx Substs<'tcx>, @@ -843,7 +843,7 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, callee_substs); let trait_ref = ty::Binder(rcvr_substs.to_trait_ref(tcx, trait_id)); - let vtbl = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); + let vtbl = fulfill_obligation(ccx, DUMMY_SP, trait_ref); // Now that we know which impl is being used, we can dispatch to // the actual function: @@ -911,7 +911,7 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, /// /// Finally, there is also the case of custom unsizing coercions, e.g. for /// smart pointers such as `Rc` and `Arc`. -fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, source_ty: ty::Ty<'tcx>, target_ty: ty::Ty<'tcx>) -> (ty::Ty<'tcx>, ty::Ty<'tcx>) { @@ -936,7 +936,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &ty::TyStruct(target_adt_def, target_substs)) => { assert_eq!(source_adt_def, target_adt_def); - let kind = custom_coerce_unsize_info(ccx.shared(), source_ty, target_ty); + let kind = custom_coerce_unsize_info(ccx, source_ty, target_ty); let coerce_index = match kind { CustomCoerceUnsized::Struct(i) => i @@ -986,7 +986,7 @@ fn create_fn_trans_item<'tcx>(tcx: &TyCtxt<'tcx>, /// Creates a `TransItem` for each method that is referenced by the vtable for /// the given trait/impl pair. -fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, trait_ty: ty::Ty<'tcx>, impl_ty: ty::Ty<'tcx>, output: &mut Vec>) { @@ -998,7 +998,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Walk all methods of the trait, including those of its supertraits for trait_ref in traits::supertraits(ccx.tcx(), poly_trait_ref) { - let vtable = fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); + let vtable = fulfill_obligation(ccx, DUMMY_SP, trait_ref); match vtable { traits::VtableImpl( traits::VtableImplData { @@ -1035,7 +1035,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, //=----------------------------------------------------------------------------- struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> { - ccx: &'b CrateContext<'a, 'tcx>, + ccx: &'b SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode, output: &'b mut Vec>, enclosing_item: Option<&'tcx hir::Item>, @@ -1546,12 +1546,12 @@ pub enum TransItemState { NotPredictedButGenerated, } -pub fn collecting_debug_information(ccx: &CrateContext) -> bool { +pub fn collecting_debug_information(ccx: &SharedCrateContext) -> bool { return cfg!(debug_assertions) && ccx.sess().opts.debugging_opts.print_trans_items.is_some(); } -pub fn print_collection_results<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { +pub fn print_collection_results<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>) { use std::hash::{Hash, SipHasher, Hasher}; if !collecting_debug_information(ccx) { diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 09d38e8946bbd..2811148abd68e 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -1133,7 +1133,7 @@ pub fn trans_static(ccx: &CrateContext, attrs: &[ast::Attribute]) -> Result { - if collector::collecting_debug_information(ccx) { + if collector::collecting_debug_information(ccx.shared()) { ccx.record_translation_item_as_generated(TransItem::Static(id)); } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index d7ec448a7f0b2..323bc338245df 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -469,6 +469,28 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { pub fn use_dll_storage_attrs(&self) -> bool { self.use_dll_storage_attrs } + + pub fn get_mir(&self, def_id: DefId) -> Option> { + if def_id.is_local() { + let node_id = self.tcx.map.as_local_node_id(def_id).unwrap(); + self.mir_map.map.get(&node_id).map(CachedMir::Ref) + } else { + if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() { + return Some(CachedMir::Owned(mir)); + } + + let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id); + let cached = mir.map(Rc::new); + if let Some(ref mir) = cached { + self.mir_cache.borrow_mut().insert(def_id, mir.clone()); + } + cached.map(CachedMir::Owned) + } + } + + pub fn translation_items(&self) -> &RefCell, TransItemState>> { + &self.translation_items + } } impl<'tcx> LocalCrateContext<'tcx> { @@ -843,21 +865,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn get_mir(&self, def_id: DefId) -> Option> { - if def_id.is_local() { - let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); - self.shared.mir_map.map.get(&node_id).map(CachedMir::Ref) - } else { - if let Some(mir) = self.shared.mir_cache.borrow().get(&def_id).cloned() { - return Some(CachedMir::Owned(mir)); - } - - let mir = self.sess().cstore.maybe_get_item_mir(self.tcx(), def_id); - let cached = mir.map(Rc::new); - if let Some(ref mir) = cached { - self.shared.mir_cache.borrow_mut().insert(def_id, mir.clone()); - } - cached.map(CachedMir::Owned) - } + self.shared.get_mir(def_id) } pub fn translation_items(&self) -> &RefCell, TransItemState>> { diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index e83580b95bcc4..898ac636c1d43 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -489,7 +489,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>, fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueKind<'tcx>) -> Block<'blk, 'tcx> { - if collector::collecting_debug_information(bcx.ccx()) { + if collector::collecting_debug_information(bcx.ccx().shared()) { bcx.ccx() .record_translation_item_as_generated(TransItem::DropGlue(g)); } From bebcb285ad187153a71296c42a02e4bb9c2297f5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 14:27:34 -0400 Subject: [PATCH 10/16] Restructure trans_crate() so that codegen unit partitioning happens before creating LocalCrateContexts. --- src/librustc_trans/back/write.rs | 3 ++- src/librustc_trans/base.rs | 43 +++++++++++++++++------------- src/librustc_trans/context.rs | 8 +++--- src/librustc_trans/partitioning.rs | 14 +++++++++- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 9f7a794185ad5..cf81777be261d 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -639,7 +639,8 @@ pub fn run_passes(sess: &Session, } // Sanity check - assert!(trans.modules.len() == sess.opts.cg.codegen_units); + assert!(trans.modules.len() == sess.opts.cg.codegen_units || + sess.opts.debugging_opts.incremental.is_some()); let tm = create_target_machine(sess); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index c89a8a930f727..a8aff88dfc7c3 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -81,7 +81,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real}; use meth; use mir; use monomorphize::{self, Instance}; -use partitioning::{self, PartitioningStrategy, InstantiationMode}; +use partitioning::{self, PartitioningStrategy, InstantiationMode, CodegenUnit}; use symbol_names_test; use tvec; use type_::Type; @@ -2186,7 +2186,8 @@ pub fn update_linkage(ccx: &CrateContext, // `llval` is a translation of an item defined in a separate // compilation unit. This only makes sense if there are at least // two compilation units. - assert!(ccx.sess().opts.cg.codegen_units > 1); + assert!(ccx.sess().opts.cg.codegen_units > 1 || + ccx.sess().opts.debugging_opts.incremental.is_some()); // `llval` is a copy of something defined elsewhere, so use // `AvailableExternallyLinkage` to avoid duplicating code in the // output. @@ -2723,12 +2724,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, check_overflow, check_dropflag); - let codegen_units = tcx.sess.opts.cg.codegen_units; + let codegen_units = collect_and_partition_translation_items(&shared_ccx); + let codegen_unit_count = codegen_units.len(); + assert!(tcx.sess.opts.cg.codegen_units == codegen_unit_count || + tcx.sess.opts.debugging_opts.incremental.is_some()); + let crate_context_list = CrateContextList::new(&shared_ccx, codegen_units); { let ccx = crate_context_list.get_ccx(0); - collect_translation_items(&ccx); // Translate all items. See `TransModVisitor` for // details on why we walk in this particular way. @@ -2818,7 +2822,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>, } } - if codegen_units > 1 { + if codegen_unit_count > 1 { internalize_symbols(&crate_context_list, &reachable_symbols.iter().map(|x| &x[..]).collect()); } @@ -2910,10 +2914,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> { } } -fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { - let time_passes = ccx.sess().time_passes(); +fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) + -> Vec> { + let time_passes = scx.sess().time_passes(); - let collection_mode = match ccx.sess().opts.debugging_opts.print_trans_items { + let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items { Some(ref s) => { let mode_string = s.to_lowercase(); let mode_string = mode_string.trim(); @@ -2924,7 +2929,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { let message = format!("Unknown codegen-item collection mode '{}'. \ Falling back to 'lazy' mode.", mode_string); - ccx.sess().warn(&message); + scx.sess().warn(&message); } TransItemCollectionMode::Lazy @@ -2934,27 +2939,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { }; let (items, reference_map) = time(time_passes, "translation item collection", || { - collector::collect_crate_translation_items(ccx.shared(), collection_mode) + collector::collect_crate_translation_items(scx, collection_mode) }); - let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() { + let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() { PartitioningStrategy::PerModule } else { - PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units) + PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units) }; let codegen_units = time(time_passes, "codegen unit partitioning", || { - partitioning::partition(ccx.tcx(), + partitioning::partition(scx.tcx(), items.iter().cloned(), strategy, &reference_map) }); - if ccx.sess().opts.debugging_opts.print_trans_items.is_some() { + if scx.sess().opts.debugging_opts.print_trans_items.is_some() { let mut item_to_cgus = HashMap::new(); - for cgu in codegen_units { - for (trans_item, linkage) in cgu.items { + for cgu in &codegen_units { + for (&trans_item, &linkage) in &cgu.items { item_to_cgus.entry(trans_item) .or_insert(Vec::new()) .push((cgu.name.clone(), linkage)); @@ -2964,7 +2969,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(ccx.tcx()); + let mut output = i.to_string(scx.tcx()); output.push_str(" @@"); let mut empty = Vec::new(); let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); @@ -3003,10 +3008,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { println!("TRANS_ITEM {}", item); } - let mut ccx_map = ccx.translation_items().borrow_mut(); + let mut ccx_map = scx.translation_items().borrow_mut(); for cgi in items { ccx_map.insert(cgi, TransItemState::PredictedButNotGenerated); } } + + codegen_units } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 323bc338245df..9f5fe28ee8218 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -28,6 +28,7 @@ use mir::CachedMir; use monomorphize::Instance; use collector::{TransItem, TransItemState}; +use partitioning::CodegenUnit; use type_::{Type, TypeNames}; use rustc::ty::subst::{Substs, VecPerParamSpace}; use rustc::ty::{self, Ty, TyCtxt}; @@ -196,11 +197,12 @@ pub struct CrateContextList<'a, 'tcx: 'a> { impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { pub fn new(shared_ccx: &'a SharedCrateContext<'a, 'tcx>, - local_count: usize) + codegen_units: Vec>) -> CrateContextList<'a, 'tcx> { CrateContextList { shared: shared_ccx, - local_ccxs: (0..local_count).map(|index| { + // FIXME: We don't actually use the codegen unit partitioning yet. + local_ccxs: codegen_units.iter().map(|cgu| { // Append ".rs" to crate name as LLVM module identifier. // // LLVM code generator emits a ".file filename" directive @@ -209,7 +211,7 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { // crashes if the module identifier is same as other symbols // such as a function name in the module. // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 - let llmod_id = format!("{}.{}.rs", shared_ccx.link_meta.crate_name, index); + let llmod_id = format!("{}.rs", cgu.name); LocalCrateContext::new(shared_ccx, &llmod_id[..]) }).collect() } diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index 250292ee684de..6e50292a91a58 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -182,7 +182,19 @@ pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>, // easily determine which declarations need to be placed within each one. let post_declarations = place_declarations(post_inlining, reference_map); - post_declarations.0 + let mut final_partitioning = post_declarations.0; + + if final_partitioning.len() == 0 { + // Some crates don't contain anything that will result in a translation + // item. We still want to have at least one (empty) codegen unit in that + // case. + final_partitioning.push(CodegenUnit { + name: token::intern_and_get_ident(&format!("{}.0", tcx.crate_name)[..]), + items: FnvHashMap() + }); + } + + final_partitioning } struct PreInliningPartitioning<'tcx> { From a8e34dfc29df9ca817e9d1e91f3e49f6d405fe28 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 15:21:17 -0400 Subject: [PATCH 11/16] trans: Make partitioning available in LocalCrateContext. --- src/librustc_trans/context.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 9f5fe28ee8218..9692d31ee1451 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -96,6 +96,7 @@ pub struct LocalCrateContext<'tcx> { llmod: ModuleRef, llcx: ContextRef, tn: TypeNames, // FIXME: This seems to be largely unused. + codegen_unit: CodegenUnit<'tcx>, needs_unwind_cleanup_cache: RefCell, bool>>, fn_pointer_shims: RefCell, ValueRef>>, drop_glues: RefCell, ValueRef>>, @@ -201,18 +202,8 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { -> CrateContextList<'a, 'tcx> { CrateContextList { shared: shared_ccx, - // FIXME: We don't actually use the codegen unit partitioning yet. - local_ccxs: codegen_units.iter().map(|cgu| { - // Append ".rs" to crate name as LLVM module identifier. - // - // LLVM code generator emits a ".file filename" directive - // for ELF backends. Value of the "filename" is set as the - // LLVM module identifier. Due to a LLVM MC bug[1], LLVM - // crashes if the module identifier is same as other symbols - // such as a function name in the module. - // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 - let llmod_id = format!("{}.rs", cgu.name); - LocalCrateContext::new(shared_ccx, &llmod_id[..]) + local_ccxs: codegen_units.into_iter().map(|codegen_unit| { + LocalCrateContext::new(shared_ccx, codegen_unit) }).collect() } } @@ -497,10 +488,21 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { impl<'tcx> LocalCrateContext<'tcx> { fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>, - name: &str) + codegen_unit: CodegenUnit<'tcx>) -> LocalCrateContext<'tcx> { unsafe { - let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, name); + // Append ".rs" to LLVM module identifier. + // + // LLVM code generator emits a ".file filename" directive + // for ELF backends. Value of the "filename" is set as the + // LLVM module identifier. Due to a LLVM MC bug[1], LLVM + // crashes if the module identifier is same as other symbols + // such as a function name in the module. + // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 + let llmod_id = format!("{}.rs", codegen_unit.name); + + let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, + &llmod_id[..]); let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { Some(debuginfo::CrateDebugContext::new(llmod)) @@ -511,6 +513,7 @@ impl<'tcx> LocalCrateContext<'tcx> { let local_ccx = LocalCrateContext { llmod: llmod, llcx: llcx, + codegen_unit: codegen_unit, tn: TypeNames::new(), needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()), fn_pointer_shims: RefCell::new(FnvHashMap()), @@ -668,6 +671,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local().llcx } + pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> { + &self.local().codegen_unit + } + pub fn td(&self) -> llvm::TargetDataRef { unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) } } From 0142336a2a447e9883ae4dd6db98354154ba08e3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 16:53:59 -0400 Subject: [PATCH 12/16] trans: Add some explanatory comments to trans::context types. --- src/librustc_trans/context.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 9692d31ee1451..b182f4de26b22 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -190,6 +190,9 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> { } } +/// This list owns a number of LocalCrateContexts and binds them to their common +/// SharedCrateContext. This type just exists as a convenience, something to +/// pass around all LocalCrateContexts with and get an iterator over them. pub struct CrateContextList<'a, 'tcx: 'a> { shared: &'a SharedCrateContext<'a, 'tcx>, local_ccxs: Vec>, @@ -229,6 +232,9 @@ impl<'a, 'tcx: 'a> CrateContextList<'a, 'tcx> { } } +/// A CrateContext value binds together one LocalCrateContext with the +/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to +/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans. pub struct CrateContext<'a, 'tcx: 'a> { shared: &'a SharedCrateContext<'a, 'tcx>, local_ccxs: &'a [LocalCrateContext<'tcx>], From b89a5d1f7c8fb7fcfbbbf06544be9bfaf2c25bf8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 17:00:59 -0400 Subject: [PATCH 13/16] Make FixedCount partitioning handle case where codegen units have to be added. --- src/librustc_trans/partitioning.rs | 35 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index 6e50292a91a58..7b21b61209759 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -182,19 +182,7 @@ pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>, // easily determine which declarations need to be placed within each one. let post_declarations = place_declarations(post_inlining, reference_map); - let mut final_partitioning = post_declarations.0; - - if final_partitioning.len() == 0 { - // Some crates don't contain anything that will result in a translation - // item. We still want to have at least one (empty) codegen unit in that - // case. - final_partitioning.push(CodegenUnit { - name: token::intern_and_get_ident(&format!("{}.0", tcx.crate_name)[..]), - items: FnvHashMap() - }); - } - - final_partitioning + post_declarations.0 } struct PreInliningPartitioning<'tcx> { @@ -268,10 +256,6 @@ fn place_root_translation_items<'tcx, I>(tcx: &TyCtxt<'tcx>, fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>, target_cgu_count: usize, crate_name: &str) { - if target_cgu_count >= initial_partitioning.codegen_units.len() { - return; - } - assert!(target_cgu_count >= 1); let codegen_units = &mut initial_partitioning.codegen_units; @@ -290,7 +274,22 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning< } for (index, cgu) in codegen_units.iter_mut().enumerate() { - cgu.name = token::intern_and_get_ident(&format!("{}.{}", crate_name, index)[..]); + cgu.name = numbered_codegen_unit_name(crate_name, index); + } + + // If the initial partitioning contained less than target_cgu_count to begin + // with, we won't have enough codegen units here, so add a empty units until + // we reach the target count + while codegen_units.len() < target_cgu_count { + let index = codegen_units.len(); + codegen_units.push(CodegenUnit { + name: numbered_codegen_unit_name(crate_name, index), + items: FnvHashMap() + }); + } + + fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString { + token::intern_and_get_ident(&format!("{}.{}", crate_name, index)[..]) } } From 86a691a5c7d183bc1e19d53832ea40cf41fa7ccd Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 17:07:36 -0400 Subject: [PATCH 14/16] trans: Consistently name SharedCrateContext instances 'scx' --- src/librustc_trans/base.rs | 20 +-- src/librustc_trans/collector.rs | 210 ++++++++++++++++---------------- src/librustc_trans/common.rs | 8 +- 3 files changed, 119 insertions(+), 119 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index a8aff88dfc7c3..4204d810d89a9 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } -pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &SharedCrateContext<'ccx, 'tcx>, +pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> CustomCoerceUnsized { @@ -674,13 +674,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &SharedCrateContext<'ccx, 'tcx subst::VecPerParamSpace::empty()); let trait_ref = ty::Binder(ty::TraitRef { - def_id: ccx.tcx().lang_items.coerce_unsized_trait().unwrap(), - substs: ccx.tcx().mk_substs(trait_substs) + def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(), + substs: scx.tcx().mk_substs(trait_substs) }); - match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + match fulfill_obligation(scx, DUMMY_SP, trait_ref) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { - ccx.tcx().custom_coerce_unsized_kind(impl_def_id) + scx.tcx().custom_coerce_unsized_kind(impl_def_id) } vtable => { bug!("invalid CoerceUnsized vtable: {:?}", vtable); @@ -2660,10 +2660,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter { /// /// This list is later used by linkers to determine the set of symbols needed to /// be exposed from a dynamic library and it's also encoded into the metadata. -pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet { - ccx.reachable().iter().map(|x| *x).filter(|id| { +pub fn filter_reachable_ids(scx: &SharedCrateContext) -> NodeSet { + scx.reachable().iter().map(|x| *x).filter(|id| { // First, only worry about nodes which have a symbol name - ccx.item_symbols().borrow().contains_key(id) + scx.item_symbols().borrow().contains_key(id) }).filter(|&id| { // Next, we want to ignore some FFI functions that are not exposed from // this crate. Reachable FFI functions can be lumped into two @@ -2678,9 +2678,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet { // // As a result, if this id is an FFI item (foreign item) then we only // let it through if it's included statically. - match ccx.tcx().map.get(id) { + match scx.tcx().map.get(id) { hir_map::NodeForeignItem(..) => { - ccx.sess().cstore.is_statically_included_foreign_item(id) + scx.sess().cstore.is_statically_included_foreign_item(id) } _ => true, } diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index e815d7b61d7b1..ba924d6ae3ef6 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -319,14 +319,14 @@ impl<'tcx> ReferenceMap<'tcx> { } } -pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode) -> (FnvHashSet>, ReferenceMap<'tcx>) { // We are not tracking dependencies of this pass as it has to be re-executed // every time no matter what. - ccx.tcx().dep_graph.with_ignore(|| { - let roots = collect_roots(ccx, mode); + scx.tcx().dep_graph.with_ignore(|| { + let roots = collect_roots(scx, mode); debug!("Building translation item graph, beginning at roots"); let mut visited = FnvHashSet(); @@ -334,7 +334,7 @@ pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &SharedCrateContext<'a, 't let mut reference_map = ReferenceMap::new(); for root in roots { - collect_items_rec(ccx, + collect_items_rec(scx, root, &mut visited, &mut recursion_depths, @@ -347,7 +347,7 @@ pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &SharedCrateContext<'a, 't // Find all non-generic items by walking the HIR. These items serve as roots to // start monomorphizing from. -fn collect_roots<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode) -> Vec> { debug!("Collecting roots"); @@ -355,20 +355,20 @@ fn collect_roots<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, { let mut visitor = RootCollector { - ccx: ccx, + scx: scx, mode: mode, output: &mut roots, enclosing_item: None, }; - ccx.tcx().map.krate().visit_all_items(&mut visitor); + scx.tcx().map.krate().visit_all_items(&mut visitor); } roots } // Collect all monomorphized translation items reachable from `starting_point` -fn collect_items_rec<'a, 'tcx: 'a>(ccx: &SharedCrateContext<'a, 'tcx>, +fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, starting_point: TransItem<'tcx>, visited: &mut FnvHashSet>, recursion_depths: &mut DefIdMap, @@ -377,36 +377,36 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &SharedCrateContext<'a, 'tcx>, // We've been here already, no need to search again. return; } - debug!("BEGIN collect_items_rec({})", starting_point.to_string(ccx.tcx())); + debug!("BEGIN collect_items_rec({})", starting_point.to_string(scx.tcx())); let mut neighbors = Vec::new(); let recursion_depth_reset; match starting_point { TransItem::DropGlue(t) => { - find_drop_glue_neighbors(ccx, t, &mut neighbors); + find_drop_glue_neighbors(scx, t, &mut neighbors); recursion_depth_reset = None; } TransItem::Static(node_id) => { - let def_id = ccx.tcx().map.local_def_id(node_id); - let ty = ccx.tcx().lookup_item_type(def_id).ty; - let ty = glue::get_drop_glue_type(ccx.tcx(), ty); + let def_id = scx.tcx().map.local_def_id(node_id); + let ty = scx.tcx().lookup_item_type(def_id).ty; + let ty = glue::get_drop_glue_type(scx.tcx(), ty); neighbors.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); recursion_depth_reset = None; } TransItem::Fn(instance) => { // Keep track of the monomorphization recursion depth - recursion_depth_reset = Some(check_recursion_limit(ccx.tcx(), + recursion_depth_reset = Some(check_recursion_limit(scx.tcx(), instance, recursion_depths)); // Scan the MIR in order to find function calls, closures, and // drop-glue - let mir = errors::expect(ccx.sess().diagnostic(), ccx.get_mir(instance.def), + let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def), || format!("Could not find MIR for function: {}", instance)); let mut visitor = MirNeighborCollector { - ccx: ccx, + scx: scx, mir: &mir, output: &mut neighbors, param_substs: instance.substs @@ -419,17 +419,17 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &SharedCrateContext<'a, 'tcx>, } } - record_references(ccx.tcx(), starting_point, &neighbors[..], reference_map); + record_references(scx.tcx(), starting_point, &neighbors[..], reference_map); for neighbour in neighbors { - collect_items_rec(ccx, neighbour, visited, recursion_depths, reference_map); + collect_items_rec(scx, neighbour, visited, recursion_depths, reference_map); } if let Some((def_id, depth)) = recursion_depth_reset { recursion_depths.insert(def_id, depth); } - debug!("END collect_items_rec({})", starting_point.to_string(ccx.tcx())); + debug!("END collect_items_rec({})", starting_point.to_string(scx.tcx())); } fn record_references<'tcx>(tcx: &TyCtxt<'tcx>, @@ -473,7 +473,7 @@ fn check_recursion_limit<'tcx>(tcx: &TyCtxt<'tcx>, } struct MirNeighborCollector<'a, 'tcx: 'a> { - ccx: &'a SharedCrateContext<'a, 'tcx>, + scx: &'a SharedCrateContext<'a, 'tcx>, mir: &'a mir::Mir<'tcx>, output: &'a mut Vec>, param_substs: &'tcx Substs<'tcx> @@ -487,8 +487,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match *rvalue { mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id, ref substs), _) => { - assert!(can_have_local_instance(self.ccx.tcx(), def_id)); - let trans_item = create_fn_trans_item(self.ccx.tcx(), + assert!(can_have_local_instance(self.scx.tcx(), def_id)); + let trans_item = create_fn_trans_item(self.scx.tcx(), def_id, substs.func_substs, self.param_substs); @@ -498,21 +498,21 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast(mir::CastKind::Unsize, ref operand, target_ty) => { - let target_ty = monomorphize::apply_param_substs(self.ccx.tcx(), + let target_ty = monomorphize::apply_param_substs(self.scx.tcx(), self.param_substs, &target_ty); - let source_ty = self.mir.operand_ty(self.ccx.tcx(), operand); - let source_ty = monomorphize::apply_param_substs(self.ccx.tcx(), + let source_ty = self.mir.operand_ty(self.scx.tcx(), operand); + let source_ty = monomorphize::apply_param_substs(self.scx.tcx(), self.param_substs, &source_ty); - let (source_ty, target_ty) = find_vtable_types_for_unsizing(self.ccx, + let (source_ty, target_ty) = find_vtable_types_for_unsizing(self.scx, source_ty, target_ty); // This could also be a different Unsize instruction, like // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. if target_ty.is_trait() && !source_ty.is_trait() { - create_trans_items_for_vtable_methods(self.ccx, + create_trans_items_for_vtable_methods(self.scx, target_ty, source_ty, self.output); @@ -520,15 +520,15 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } mir::Rvalue::Box(_) => { let exchange_malloc_fn_def_id = - self.ccx + self.scx .tcx() .lang_items .require(ExchangeMallocFnLangItem) - .unwrap_or_else(|e| self.ccx.sess().fatal(&e)); + .unwrap_or_else(|e| self.scx.sess().fatal(&e)); - assert!(can_have_local_instance(self.ccx.tcx(), exchange_malloc_fn_def_id)); + assert!(can_have_local_instance(self.scx.tcx(), exchange_malloc_fn_def_id)); let exchange_malloc_fn_trans_item = - create_fn_trans_item(self.ccx.tcx(), + create_fn_trans_item(self.scx.tcx(), exchange_malloc_fn_def_id, &Substs::empty(), self.param_substs); @@ -547,14 +547,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { debug!("visiting lvalue {:?}", *lvalue); if let mir_visit::LvalueContext::Drop = context { - let ty = self.mir.lvalue_ty(self.ccx.tcx(), lvalue) - .to_ty(self.ccx.tcx()); + let ty = self.mir.lvalue_ty(self.scx.tcx(), lvalue) + .to_ty(self.scx.tcx()); - let ty = monomorphize::apply_param_substs(self.ccx.tcx(), + let ty = monomorphize::apply_param_substs(self.scx.tcx(), self.param_substs, &ty); - let ty = self.ccx.tcx().erase_regions(&ty); - let ty = glue::get_drop_glue_type(self.ccx.tcx(), ty); + let ty = self.scx.tcx().erase_regions(&ty); + let ty = glue::get_drop_glue_type(self.scx.tcx(), ty); self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); } @@ -582,7 +582,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // // Calling do_static_dispatch() here will map the def_id of // `std::cmp::partial_cmp` to the def_id of `i32::partial_cmp` - let dispatched = do_static_dispatch(self.ccx, + let dispatched = do_static_dispatch(self.scx, callee_def_id, callee_substs, self.param_substs); @@ -593,9 +593,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // object shim or a closure that is handled differently), // we check if the callee is something that will actually // result in a translation item ... - if can_result_in_trans_item(self.ccx.tcx(), callee_def_id) { + if can_result_in_trans_item(self.scx.tcx(), callee_def_id) { // ... and create one if it does. - let trans_item = create_fn_trans_item(self.ccx.tcx(), + let trans_item = create_fn_trans_item(self.scx.tcx(), callee_def_id, callee_substs, self.param_substs); @@ -644,7 +644,7 @@ fn can_have_local_instance<'tcx>(tcx: &TyCtxt<'tcx>, def_id.is_local() || tcx.sess.cstore.is_item_mir_available(def_id) } -fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, dg: DropGlueKind<'tcx>, output: &mut Vec>) { let ty = match dg { @@ -656,19 +656,19 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, } }; - debug!("find_drop_glue_neighbors: {}", type_to_string(ccx.tcx(), ty)); + debug!("find_drop_glue_neighbors: {}", type_to_string(scx.tcx(), ty)); // Make sure the exchange_free_fn() lang-item gets translated if // there is a boxed value. if let ty::TyBox(_) = ty.sty { - let exchange_free_fn_def_id = ccx.tcx() + let exchange_free_fn_def_id = scx.tcx() .lang_items .require(ExchangeFreeFnLangItem) - .unwrap_or_else(|e| ccx.sess().fatal(&e)); + .unwrap_or_else(|e| scx.sess().fatal(&e)); - assert!(can_have_local_instance(ccx.tcx(), exchange_free_fn_def_id)); + assert!(can_have_local_instance(scx.tcx(), exchange_free_fn_def_id)); let exchange_free_fn_trans_item = - create_fn_trans_item(ccx.tcx(), + create_fn_trans_item(scx.tcx(), exchange_free_fn_def_id, &Substs::empty(), &Substs::empty()); @@ -687,12 +687,12 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, if let Some(destructor_did) = destructor_did { use rustc::ty::ToPolyTraitRef; - let drop_trait_def_id = ccx.tcx() + let drop_trait_def_id = scx.tcx() .lang_items .drop_trait() .unwrap(); - let self_type_substs = ccx.tcx().mk_substs( + let self_type_substs = scx.tcx().mk_substs( Substs::empty().with_self_ty(ty)); let trait_ref = ty::TraitRef { @@ -700,13 +700,13 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, substs: self_type_substs, }.to_poly_trait_ref(); - let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) { + let substs = match fulfill_obligation(scx, DUMMY_SP, trait_ref) { traits::VtableImpl(data) => data.substs, _ => bug!() }; - if can_have_local_instance(ccx.tcx(), destructor_did) { - let trans_item = create_fn_trans_item(ccx.tcx(), + if can_have_local_instance(scx.tcx(), destructor_did) { + let trans_item = create_fn_trans_item(scx.tcx(), destructor_did, substs, &Substs::empty()); @@ -737,35 +737,35 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, ty::TyStruct(ref adt_def, substs) | ty::TyEnum(ref adt_def, substs) => { for field in adt_def.all_fields() { - let field_type = monomorphize::apply_param_substs(ccx.tcx(), + let field_type = monomorphize::apply_param_substs(scx.tcx(), substs, &field.unsubst_ty()); - let field_type = glue::get_drop_glue_type(ccx.tcx(), field_type); + let field_type = glue::get_drop_glue_type(scx.tcx(), field_type); - if glue::type_needs_drop(ccx.tcx(), field_type) { + if glue::type_needs_drop(scx.tcx(), field_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(field_type))); } } } ty::TyClosure(_, ref substs) => { for upvar_ty in &substs.upvar_tys { - let upvar_ty = glue::get_drop_glue_type(ccx.tcx(), upvar_ty); - if glue::type_needs_drop(ccx.tcx(), upvar_ty) { + let upvar_ty = glue::get_drop_glue_type(scx.tcx(), upvar_ty); + if glue::type_needs_drop(scx.tcx(), upvar_ty) { output.push(TransItem::DropGlue(DropGlueKind::Ty(upvar_ty))); } } } ty::TyBox(inner_type) | ty::TyArray(inner_type, _) => { - let inner_type = glue::get_drop_glue_type(ccx.tcx(), inner_type); - if glue::type_needs_drop(ccx.tcx(), inner_type) { + let inner_type = glue::get_drop_glue_type(scx.tcx(), inner_type); + if glue::type_needs_drop(scx.tcx(), inner_type) { output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type))); } } ty::TyTuple(ref args) => { for arg in args { - let arg = glue::get_drop_glue_type(ccx.tcx(), arg); - if glue::type_needs_drop(ccx.tcx(), arg) { + let arg = glue::get_drop_glue_type(scx.tcx(), arg); + if glue::type_needs_drop(scx.tcx(), arg) { output.push(TransItem::DropGlue(DropGlueKind::Ty(arg))); } } @@ -779,25 +779,25 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, } } -fn do_static_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, fn_def_id: DefId, fn_substs: &'tcx Substs<'tcx>, param_substs: &'tcx Substs<'tcx>) -> Option<(DefId, &'tcx Substs<'tcx>)> { debug!("do_static_dispatch(fn_def_id={}, fn_substs={:?}, param_substs={:?})", - def_id_to_string(ccx.tcx(), fn_def_id), + def_id_to_string(scx.tcx(), fn_def_id), fn_substs, param_substs); - let is_trait_method = ccx.tcx().trait_of_item(fn_def_id).is_some(); + let is_trait_method = scx.tcx().trait_of_item(fn_def_id).is_some(); if is_trait_method { - match ccx.tcx().impl_or_trait_item(fn_def_id) { + match scx.tcx().impl_or_trait_item(fn_def_id) { ty::MethodTraitItem(ref method) => { match method.container { ty::TraitContainer(trait_def_id) => { debug!(" => trait method, attempting to find impl"); - do_static_trait_method_dispatch(ccx, + do_static_trait_method_dispatch(scx, method, trait_def_id, fn_substs, @@ -822,19 +822,19 @@ fn do_static_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, // Given a trait-method and substitution information, find out the actual // implementation of the trait method. -fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, trait_method: &ty::Method, trait_id: DefId, callee_substs: &'tcx Substs<'tcx>, param_substs: &'tcx Substs<'tcx>) -> Option<(DefId, &'tcx Substs<'tcx>)> { - let tcx = ccx.tcx(); + let tcx = scx.tcx(); debug!("do_static_trait_method_dispatch(trait_method={}, \ trait_id={}, \ callee_substs={:?}, \ param_substs={:?}", - def_id_to_string(ccx.tcx(), trait_method.def_id), - def_id_to_string(ccx.tcx(), trait_id), + def_id_to_string(scx.tcx(), trait_method.def_id), + def_id_to_string(scx.tcx(), trait_id), callee_substs, param_substs); @@ -843,7 +843,7 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, callee_substs); let trait_ref = ty::Binder(rcvr_substs.to_trait_ref(tcx, trait_id)); - let vtbl = fulfill_obligation(ccx, DUMMY_SP, trait_ref); + let vtbl = fulfill_obligation(scx, DUMMY_SP, trait_ref); // Now that we know which impl is being used, we can dispatch to // the actual function: @@ -911,7 +911,7 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, /// /// Finally, there is also the case of custom unsizing coercions, e.g. for /// smart pointers such as `Rc` and `Arc`. -fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, source_ty: ty::Ty<'tcx>, target_ty: ty::Ty<'tcx>) -> (ty::Ty<'tcx>, ty::Ty<'tcx>) { @@ -925,10 +925,10 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { let (inner_source, inner_target) = (a, b); - if !type_is_sized(ccx.tcx(), inner_source) { + if !type_is_sized(scx.tcx(), inner_source) { (inner_source, inner_target) } else { - ccx.tcx().struct_lockstep_tails(inner_source, inner_target) + scx.tcx().struct_lockstep_tails(inner_source, inner_target) } } @@ -936,7 +936,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, &ty::TyStruct(target_adt_def, target_substs)) => { assert_eq!(source_adt_def, target_adt_def); - let kind = custom_coerce_unsize_info(ccx, source_ty, target_ty); + let kind = custom_coerce_unsize_info(scx, source_ty, target_ty); let coerce_index = match kind { CustomCoerceUnsized::Struct(i) => i @@ -948,10 +948,10 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, assert!(coerce_index < source_fields.len() && source_fields.len() == target_fields.len()); - find_vtable_types_for_unsizing(ccx, - source_fields[coerce_index].ty(ccx.tcx(), + find_vtable_types_for_unsizing(scx, + source_fields[coerce_index].ty(scx.tcx(), source_substs), - target_fields[coerce_index].ty(ccx.tcx(), + target_fields[coerce_index].ty(scx.tcx(), target_substs)) } _ => bug!("find_vtable_types_for_unsizing: invalid coercion {:?} -> {:?}", @@ -986,33 +986,33 @@ fn create_fn_trans_item<'tcx>(tcx: &TyCtxt<'tcx>, /// Creates a `TransItem` for each method that is referenced by the vtable for /// the given trait/impl pair. -fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, trait_ty: ty::Ty<'tcx>, impl_ty: ty::Ty<'tcx>, output: &mut Vec>) { assert!(!trait_ty.needs_subst() && !impl_ty.needs_subst()); if let ty::TyTrait(ref trait_ty) = trait_ty.sty { - let poly_trait_ref = trait_ty.principal_trait_ref_with_self_ty(ccx.tcx(), + let poly_trait_ref = trait_ty.principal_trait_ref_with_self_ty(scx.tcx(), impl_ty); // Walk all methods of the trait, including those of its supertraits - for trait_ref in traits::supertraits(ccx.tcx(), poly_trait_ref) { - let vtable = fulfill_obligation(ccx, DUMMY_SP, trait_ref); + for trait_ref in traits::supertraits(scx.tcx(), poly_trait_ref) { + let vtable = fulfill_obligation(scx, DUMMY_SP, trait_ref); match vtable { traits::VtableImpl( traits::VtableImplData { impl_def_id, substs, nested: _ }) => { - let items = meth::get_vtable_methods(ccx.tcx(), impl_def_id, substs) + let items = meth::get_vtable_methods(scx.tcx(), impl_def_id, substs) .into_iter() // filter out None values .filter_map(|opt_impl_method| opt_impl_method) // create translation items .filter_map(|impl_method| { - if can_have_local_instance(ccx.tcx(), impl_method.method.def_id) { - Some(create_fn_trans_item(ccx.tcx(), + if can_have_local_instance(scx.tcx(), impl_method.method.def_id) { + Some(create_fn_trans_item(scx.tcx(), impl_method.method.def_id, &impl_method.substs, &Substs::empty())) @@ -1035,7 +1035,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &SharedCrateContext<'a, //=----------------------------------------------------------------------------- struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> { - ccx: &'b SharedCrateContext<'a, 'tcx>, + scx: &'b SharedCrateContext<'a, 'tcx>, mode: TransItemCollectionMode, output: &'b mut Vec>, enclosing_item: Option<&'tcx hir::Item>, @@ -1060,7 +1060,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemImpl(..) => { if self.mode == TransItemCollectionMode::Eager { - create_trans_items_for_default_impls(self.ccx.tcx(), + create_trans_items_for_default_impls(self.scx.tcx(), item, self.output); } @@ -1070,35 +1070,35 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemStruct(_, ref generics) => { if !generics.is_parameterized() { let ty = { - let tables = self.ccx.tcx().tables.borrow(); + let tables = self.scx.tcx().tables.borrow(); tables.node_types[&item.id] }; if self.mode == TransItemCollectionMode::Eager { debug!("RootCollector: ADT drop-glue for {}", - def_id_to_string(self.ccx.tcx(), - self.ccx.tcx().map.local_def_id(item.id))); + def_id_to_string(self.scx.tcx(), + self.scx.tcx().map.local_def_id(item.id))); - let ty = glue::get_drop_glue_type(self.ccx.tcx(), ty); + let ty = glue::get_drop_glue_type(self.scx.tcx(), ty); self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); } } } hir::ItemStatic(..) => { debug!("RootCollector: ItemStatic({})", - def_id_to_string(self.ccx.tcx(), - self.ccx.tcx().map.local_def_id(item.id))); + def_id_to_string(self.scx.tcx(), + self.scx.tcx().map.local_def_id(item.id))); self.output.push(TransItem::Static(item.id)); } hir::ItemFn(_, _, constness, _, ref generics, _) => { if !generics.is_type_parameterized() && constness == hir::Constness::NotConst { - let def_id = self.ccx.tcx().map.local_def_id(item.id); + let def_id = self.scx.tcx().map.local_def_id(item.id); debug!("RootCollector: ItemFn({})", - def_id_to_string(self.ccx.tcx(), def_id)); + def_id_to_string(self.scx.tcx(), def_id)); - let instance = Instance::mono(self.ccx.tcx(), def_id); + let instance = Instance::mono(self.scx.tcx(), def_id); self.output.push(TransItem::Fn(instance)); } } @@ -1115,7 +1115,7 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { constness, .. }, _) if constness == hir::Constness::NotConst => { - let hir_map = &self.ccx.tcx().map; + let hir_map = &self.scx.tcx().map; let parent_node_id = hir_map.get_parent_node(ii.id); let is_impl_generic = match hir_map.expect_item(parent_node_id) { &hir::Item { @@ -1130,12 +1130,12 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> { }; if !generics.is_type_parameterized() && !is_impl_generic { - let def_id = self.ccx.tcx().map.local_def_id(ii.id); + let def_id = self.scx.tcx().map.local_def_id(ii.id); debug!("RootCollector: MethodImplItem({})", - def_id_to_string(self.ccx.tcx(), def_id)); + def_id_to_string(self.scx.tcx(), def_id)); - let instance = Instance::mono(self.ccx.tcx(), def_id); + let instance = Instance::mono(self.scx.tcx(), def_id); self.output.push(TransItem::Fn(instance)); } } @@ -1546,15 +1546,15 @@ pub enum TransItemState { NotPredictedButGenerated, } -pub fn collecting_debug_information(ccx: &SharedCrateContext) -> bool { +pub fn collecting_debug_information(scx: &SharedCrateContext) -> bool { return cfg!(debug_assertions) && - ccx.sess().opts.debugging_opts.print_trans_items.is_some(); + scx.sess().opts.debugging_opts.print_trans_items.is_some(); } -pub fn print_collection_results<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>) { +pub fn print_collection_results<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) { use std::hash::{Hash, SipHasher, Hasher}; - if !collecting_debug_information(ccx) { + if !collecting_debug_information(scx) { return; } @@ -1564,14 +1564,14 @@ pub fn print_collection_results<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>) { s.finish() } - let trans_items = ccx.translation_items().borrow(); + let trans_items = scx.translation_items().borrow(); { // Check for duplicate item keys let mut item_keys = FnvHashMap(); for (item, item_state) in trans_items.iter() { - let k = item.to_string(ccx.tcx()); + let k = item.to_string(scx.tcx()); if item_keys.contains_key(&k) { let prev: (TransItem, TransItemState) = item_keys[&k]; @@ -1599,7 +1599,7 @@ pub fn print_collection_results<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>) { let mut generated = FnvHashSet(); for (item, item_state) in trans_items.iter() { - let item_key = item.to_string(ccx.tcx()); + let item_key = item.to_string(scx.tcx()); match *item_state { TransItemState::PredictedAndGenerated => { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 65d307cec688d..dc3da79c22612 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -1052,17 +1052,17 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &hir::Expr) -> /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should /// guarantee to us that all nested obligations *could be* resolved if we wanted to. -pub fn fulfill_obligation<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, +pub fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, span: Span, trait_ref: ty::PolyTraitRef<'tcx>) -> traits::Vtable<'tcx, ()> { - let tcx = ccx.tcx(); + let tcx = scx.tcx(); // Remove any references to regions; this helps improve caching. let trait_ref = tcx.erase_regions(&trait_ref); - ccx.trait_cache().memoize(trait_ref, || { + scx.trait_cache().memoize(trait_ref, || { debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}", trait_ref, trait_ref.def_id()); @@ -1090,7 +1090,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &SharedCrateContext<'a, 'tcx>, debug!("Encountered ambiguity selecting `{:?}` during trans, \ presuming due to overflow", trait_ref); - ccx.sess().span_fatal( + tcx.sess.span_fatal( span, "reached the recursion limit during monomorphization \ (selection ambiguity)"); From 00eabcbefab39612a56ef958a213825207697323 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 6 May 2016 17:09:18 -0400 Subject: [PATCH 15/16] trans::context: Remove some tcx::tls wackiness --- src/librustc_trans/context.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index b182f4de26b22..88edddad8c361 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -183,10 +183,7 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> { type Key = ty::PolyTraitRef<'tcx>; type Value = traits::Vtable<'tcx, ()>; fn to_dep_node(key: &ty::PolyTraitRef<'tcx>) -> DepNode { - ty::tls::with(|tcx| { - let lifted_key = tcx.lift(key).unwrap(); - lifted_key.to_poly_trait_predicate().dep_node() - }) + key.to_poly_trait_predicate().dep_node() } } From 118cc9e8e1fd72ea59c44c99a3ef3cc8abf9bbaf Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 9 May 2016 16:15:04 -0400 Subject: [PATCH 16/16] Fix some rebasing fallout. --- src/librustc_trans/context.rs | 2 +- src/librustc_trans/mir/constant.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 88edddad8c361..24095929f4f98 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -756,7 +756,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } pub fn statics<'a>(&'a self) -> &'a RefCell> { - &self.local.statics + &self.local().statics } pub fn impl_method_cache<'a>(&'a self) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 9320617983772..267d9e9a23a66 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -233,7 +233,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let trait_id = trait_item.container().id(); let substs = instance.substs; let trait_ref = ty::Binder(substs.to_trait_ref(ccx.tcx(), trait_id)); - let vtable = common::fulfill_obligation(ccx, DUMMY_SP, trait_ref); + let vtable = common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); if let traits::VtableImpl(vtable_impl) = vtable { let name = ccx.tcx().item_name(instance.def); for ac in ccx.tcx().associated_consts(vtable_impl.impl_def_id) {