make DefPath store krate and enable uniform access to crate_name/crate_disambiguator
pub node_id: ast::NodeId,
}
-pub type DefPath = Vec<DisambiguatedDefPathData>;
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub struct DefPath {
+ /// the path leading from the crate root to the item
+ pub data: Vec<DisambiguatedDefPathData>,
+
+ /// what krate root is this path relative to?
+ pub krate: ast::CrateNum,
+}
+
+impl DefPath {
+ pub fn is_local(&self) -> bool {
+ self.krate == LOCAL_CRATE
+ }
+
+ pub fn make<FN>(start_krate: ast::CrateNum,
+ start_index: DefIndex,
+ mut get_key: FN) -> DefPath
+ where FN: FnMut(DefIndex) -> DefKey
+ {
+ let mut krate = start_krate;
+ let mut data = vec![];
+ let mut index = Some(start_index);
+ loop {
+ let p = index.unwrap();
+ let key = get_key(p);
+ match key.disambiguated_data.data {
+ DefPathData::CrateRoot => {
+ assert!(key.parent.is_none());
+ break;
+ }
+ DefPathData::InlinedRoot(ref p) => {
+ assert!(key.parent.is_none());
+ assert!(!p.def_id.is_local());
+ data.extend(p.data.iter().cloned().rev());
+ krate = p.def_id.krate;
+ break;
+ }
+ _ => {
+ data.push(key.disambiguated_data);
+ index = key.parent;
+ }
+ }
+ }
+ data.reverse();
+ DefPath { data: data, krate: krate }
+ }
+}
+
/// Root of an inlined item. We track the `DefPath` of the item within
/// the original crate but also its def-id. This is kind of an
/// augmented version of a `DefPath` that includes a `DefId`. This is
/// will be the path of the item in the external crate (but the
/// path will begin with the path to the external crate).
pub fn def_path(&self, index: DefIndex) -> DefPath {
- make_def_path(index, |p| self.def_key(p))
+ DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
}
pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
}
}
-pub fn make_def_path<FN>(start_index: DefIndex, mut get_key: FN) -> DefPath
- where FN: FnMut(DefIndex) -> DefKey
-{
- let mut result = vec![];
- let mut index = Some(start_index);
- while let Some(p) = index {
- let key = get_key(p);
- match key.disambiguated_data.data {
- DefPathData::CrateRoot => {
- assert!(key.parent.is_none());
- break;
- }
- DefPathData::InlinedRoot(ref p) => {
- assert!(key.parent.is_none());
- result.extend(p.iter().cloned().rev());
- break;
- }
- _ => {
- result.push(key.disambiguated_data);
- index = key.parent;
- }
- }
- }
- result.reverse();
- result
-}
use session::Session;
use lint;
use middle;
-use middle::cstore::CrateStore;
+use middle::cstore::{CrateStore, LOCAL_CRATE};
use middle::def::DefMap;
use middle::def_id::DefId;
use middle::free_region::FreeRegionMap;
}
impl<'tcx> TyCtxt<'tcx> {
+ pub fn crate_name(&self, cnum: ast::CrateNum) -> token::InternedString {
+ if cnum == LOCAL_CRATE {
+ self.crate_name.clone()
+ } else {
+ self.sess.cstore.crate_name(cnum)
+ }
+ }
+
+ pub fn crate_disambiguator(&self, cnum: ast::CrateNum) -> token::InternedString {
+ if cnum == LOCAL_CRATE {
+ self.sess.crate_disambiguator.get().as_str()
+ } else {
+ self.sess.cstore.crate_name(cnum)
+ }
+ }
+
pub fn type_parameter_def(&self,
node_id: NodeId)
-> ty::TypeParameterDef<'tcx>
use syntax::feature_gate;
use syntax::parse;
use syntax::parse::ParseSess;
+use syntax::parse::token;
use syntax::{ast, codemap};
use syntax::feature_gate::AttributeType;
// forms a unique global identifier for the crate. It is used to allow
// multiple crates with the same name to coexist. See the
// trans::back::symbol_names module for more information.
- pub crate_disambiguator: RefCell<String>,
+ pub crate_disambiguator: Cell<ast::Name>,
pub features: RefCell<feature_gate::Features>,
/// The maximum recursion limit for potentially infinitely recursive
plugin_attributes: RefCell::new(Vec::new()),
crate_types: RefCell::new(Vec::new()),
dependency_formats: RefCell::new(FnvHashMap()),
- crate_disambiguator: RefCell::new(String::new()),
+ crate_disambiguator: Cell::new(token::intern("")),
features: RefCell::new(feature_gate::Features::new()),
recursion_limit: Cell::new(64),
next_node_id: Cell::new(1),
})?;
*sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
- *sess.crate_disambiguator.borrow_mut() = compute_crate_disambiguator(sess);
+ sess.crate_disambiguator.set(token::intern(&compute_crate_disambiguator(sess)));
time(time_passes, "recursion limit", || {
middle::recursion_limit::update_recursion_limit(sess, &krate);
// Check for (potential) conflicts with the local crate
if self.local_crate_name == crate_name &&
- &self.sess.crate_disambiguator.borrow()[..] == disambiguator {
+ self.sess.crate_disambiguator.get().as_str() == disambiguator {
span_fatal!(self.sess, span, E0519,
"the current crate is indistinguishable from one of its \
dependencies: it has the same crate-name `{}` and was \
pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath {
debug!("def_path(id={:?})", id);
- hir_map::definitions::make_def_path(id, |parent| {
- debug!("def_path: parent={:?}", parent);
- let parent_doc = cdata.lookup_item(parent);
- def_key(parent_doc)
- })
+ hir_map::DefPath::make(cdata.cnum, id, |parent| def_key(cdata, parent))
}
encode_crate_name(rbml_w, &ecx.link_meta.crate_name);
encode_crate_triple(rbml_w, &ecx.tcx.sess.opts.target_triple);
encode_hash(rbml_w, &ecx.link_meta.crate_hash);
- encode_crate_disambiguator(rbml_w, &ecx.tcx.sess.crate_disambiguator.borrow());
+ encode_crate_disambiguator(rbml_w, &ecx.tcx.sess.crate_disambiguator.get().as_str());
encode_dylib_dependency_formats(rbml_w, &ecx);
let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
-> LinkMeta {
let r = LinkMeta {
crate_name: name.to_owned(),
- crate_hash: Svh::calculate(&sess.crate_disambiguator.borrow()[..], krate),
+ crate_hash: Svh::calculate(&sess.crate_disambiguator.get().as_str(), krate),
};
info!("{:?}", r);
return r;
use serialize::hex::ToHex;
pub fn def_id_to_string<'tcx>(tcx: &ty::TyCtxt<'tcx>, def_id: DefId) -> String {
-
let def_path = tcx.def_path(def_id);
- let mut s = String::with_capacity(def_path.len() * 16);
+ def_path_to_string(tcx, &def_path)
+}
- let def_path = if def_id.is_local() {
- s.push_str(&tcx.crate_name[..]);
- s.push_str("/");
- s.push_str(&tcx.sess.crate_disambiguator.borrow()[..]);
- &def_path[..]
- } else {
- s.push_str(&tcx.sess.cstore.crate_name(def_id.krate)[..]);
- s.push_str("/");
- s.push_str(&tcx.sess.cstore.crate_disambiguator(def_id.krate));
- &def_path[1..]
- };
+pub fn def_path_to_string<'tcx>(tcx: &ty::TyCtxt<'tcx>, def_path: &DefPath) -> String {
+ let mut s = String::with_capacity(def_path.data.len() * 16);
- for component in def_path {
+ s.push_str(&tcx.crate_name(def_path.krate));
+ s.push_str("/");
+ s.push_str(&tcx.crate_disambiguator(def_path.krate));
+
+ for component in &def_path.data {
write!(s,
"::{}[{}]",
component.data.as_interned_str(),
if attr::contains_name(attrs, "no_mangle") {
// Don't mangle
let path = ccx.tcx().map.def_path_from_id(id);
- path.last().unwrap().data.to_string()
+ path.data.last().unwrap().data.to_string()
} else {
match weak_lang_items::link_name(attrs) {
Some(name) => name.to_string(),
fn push_item_name(ccx: &CrateContext,
def_id: DefId,
output: &mut String) {
- if def_id.is_local() {
- let node_id = ccx.tcx().map.as_local_node_id(def_id).unwrap();
- let inlined_from = ccx.external_srcs()
- .borrow()
- .get(&node_id)
- .map(|def_id| *def_id);
-
- if let Some(extern_def_id) = inlined_from {
- push_item_name(ccx, extern_def_id, output);
- return;
- }
+ let def_path = ccx.tcx().def_path(def_id);
- output.push_str(&ccx.link_meta().crate_name);
- output.push_str("::");
- }
+ // some_crate::
+ output.push_str(&ccx.tcx().crate_name(def_path.krate));
+ output.push_str("::");
- for part in ccx.tcx().def_path(def_id) {
+ // foo::bar::ItemName::
+ for part in ccx.tcx().def_path(def_id).data {
output.push_str(&format!("{}[{}]::",
part.data.as_interned_str(),
part.disambiguator));
}
+ // remove final "::"
output.pop();
output.pop();
}