diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 3ede60beb74..d85ea961462 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -163,6 +163,7 @@ pub trait CrateStore<'tcx> { -> ty::TypeScheme<'tcx>; fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap>; fn item_name(&self, def: DefId) -> ast::Name; + fn opt_item_name(&self, def: DefId) -> Option; fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx>; fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) @@ -345,6 +346,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { bug!("visible_parent_map") } fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") } + fn opt_item_name(&self, def: DefId) -> Option { bug!("opt_item_name") } fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx> { bug!("item_predicates") } fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index db4c0c1e9eb..1cd837e4853 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -942,7 +942,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { ppaux::parameterized(fmt, substs, variant_def.did, ppaux::Ns::Value, &[], |tcx| { - tcx.lookup_item_type(variant_def.did).generics + Some(tcx.lookup_item_type(variant_def.did).generics) })?; match variant_def.kind() { @@ -1034,8 +1034,9 @@ impl<'tcx> Debug for Literal<'tcx> { use self::Literal::*; match *self { Item { def_id, substs } => { - ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[], - |tcx| tcx.lookup_item_type(def_id).generics) + ppaux::parameterized( + fmt, substs, def_id, ppaux::Ns::Value, &[], + |tcx| Some(tcx.lookup_item_type(def_id).generics)) } Value { ref value } => { write!(fmt, "const ")?; diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index ee9983038b1..74c05feb6d1 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -13,6 +13,7 @@ use middle::cstore::LOCAL_CRATE; use hir::def_id::{DefId, CRATE_DEF_INDEX}; use ty::{self, Ty, TyCtxt}; use syntax::ast; +use syntax::parse::token; use std::cell::Cell; @@ -138,7 +139,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - cur_path.push(self.sess.cstore.item_name(cur_def)); + cur_path.push(self.sess.cstore.opt_item_name(cur_def).unwrap_or_else(|| + token::intern(""))); match visible_parent_map.get(&cur_def) { Some(&def) => cur_def = def, None => return false, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 24f0671ce61..8f42ca2abb9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2480,6 +2480,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { || self.sess.cstore.item_type(self.global_tcx(), did)) } + pub fn opt_lookup_item_type(self, did: DefId) -> Option> { + if let Some(scheme) = self.tcache.borrow_mut().get(&did) { + return Some(scheme.clone()); + } + + if did.krate == LOCAL_CRATE { + None + } else { + Some(self.sess.cstore.item_type(self.global_tcx(), did)) + } + } + /// Given the did of a trait, returns its canonical trait ref. pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> { lookup_locally_or_in_crate_store( diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 1a802064b61..bbee7afce71 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -69,15 +69,12 @@ pub enum Ns { Value } -fn number_of_supplied_defaults<'a, 'gcx, 'tcx, GG>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - substs: &subst::Substs, - space: subst::ParamSpace, - get_generics: GG) - -> usize - where GG: FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx> +fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + substs: &subst::Substs, + space: subst::ParamSpace, + generics: ty::Generics<'tcx>) + -> usize { - let generics = get_generics(tcx); - let has_self = substs.self_ty().is_some(); let ty_params = generics.types.get_slice(space); let tps = substs.types.get_slice(space); @@ -115,7 +112,8 @@ pub fn parameterized(f: &mut fmt::Formatter, projections: &[ty::ProjectionPredicate], get_generics: GG) -> fmt::Result - where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> ty::Generics<'tcx> + where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) + -> Option> { if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) { write!(f, "<{} as ", self_ty)?; @@ -176,13 +174,12 @@ pub fn parameterized(f: &mut fmt::Formatter, let num_supplied_defaults = if verbose { 0 } else { - // It is important to execute this conditionally, only if -Z - // verbose is false. Otherwise, debug logs can sometimes cause - // ICEs trying to fetch the generics early in the pipeline. This - // is kind of a hacky workaround in that -Z verbose is required to - // avoid those ICEs. ty::tls::with(|tcx| { - number_of_supplied_defaults(tcx, substs, subst::TypeSpace, get_generics) + if let Some(generics) = get_generics(tcx) { + number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics) + } else { + 0 + } }) }; @@ -310,7 +307,7 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> { trait_ref.def_id, Ns::Type, projection_bounds, - |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone()) + |tcx| Some(tcx.lookup_trait_def(trait_ref.def_id).generics.clone())) } } @@ -811,7 +808,7 @@ impl fmt::Display for ty::Binder> impl<'tcx> fmt::Display for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { parameterized(f, self.substs, self.def_id, Ns::Type, &[], - |tcx| tcx.lookup_trait_def(self.def_id).generics.clone()) + |tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone())) } } @@ -863,8 +860,9 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { } write!(f, "{} {{", bare_fn.sig.0)?; - parameterized(f, substs, def_id, Ns::Value, &[], - |tcx| tcx.lookup_item_type(def_id).generics)?; + parameterized( + f, substs, def_id, Ns::Value, &[], + |tcx| tcx.opt_lookup_item_type(def_id).map(|t| t.generics))?; write!(f, "}}") } TyFnPtr(ref bare_fn) => { @@ -887,8 +885,12 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { !tcx.tcache.borrow().contains_key(&def.did) { write!(f, "{}<..>", tcx.item_path_str(def.did)) } else { - parameterized(f, substs, def.did, Ns::Type, &[], - |tcx| tcx.lookup_item_type(def.did).generics) + parameterized( + f, substs, def.did, Ns::Type, &[], + |tcx| { + tcx.opt_lookup_item_type(def.did). + map(|t| t.generics) + }) } }) } diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 5d42f8c1d6f..3134a3844bc 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -142,6 +142,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_item_name(&self.intr, &cdata, def.index) } + fn opt_item_name(&self, def: DefId) -> Option { + self.dep_graph.read(DepNode::MetaData(def)); + let cdata = self.get_crate_data(def.krate); + decoder::maybe_get_item_name(&self.intr, &cdata, def.index) + } fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index d1153fe2d06..d97ecebc476 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -285,12 +285,17 @@ fn item_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: } fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name { - let name = reader::get_doc(item, tag_paths_data_name); - let string = name.as_str_slice(); - match intr.find(string) { - None => token::intern(string), - Some(val) => val, - } + maybe_item_name(intr, item).expect("no item in item_name") +} + +fn maybe_item_name(intr: &IdentInterner, item: rbml::Doc) -> Option { + reader::maybe_get_doc(item, tag_paths_data_name).map(|name| { + let string = name.as_str_slice(); + match intr.find(string) { + None => token::intern(string), + Some(val) => val, + } + }) } fn family_to_variant_kind<'tcx>(family: Family) -> Option { @@ -792,6 +797,11 @@ pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Nam item_name(intr, cdata.lookup_item(id)) } +pub fn maybe_get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) + -> Option { + maybe_item_name(intr, cdata.lookup_item(id)) +} + pub fn maybe_get_item_ast<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex) -> FoundAst<'tcx> { debug!("Looking up item: {:?}", id); diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index c02dd7995f1..cf84dd57d02 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -173,7 +173,7 @@ pub struct Instance<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[], - |tcx| tcx.lookup_item_type(self.def).generics) + |tcx| Some(tcx.lookup_item_type(self.def).generics)) } }