]> git.lizzy.rs Git - rust.git/commitdiff
Store and use crate-local paths to extern crates
authormitaa <mitaa.ceb@gmail.com>
Sat, 1 Aug 2015 14:14:45 +0000 (16:14 +0200)
committermitaa <mitaa.ceb@gmail.com>
Sat, 1 Aug 2015 14:14:45 +0000 (16:14 +0200)
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs

index 578507296fc13fddfa00735f6eda55719d86f500..f4561d68906fe09e7b10e23a2eac9508f1f83bf1 100644 (file)
@@ -34,6 +34,7 @@
 use syntax::parse;
 use syntax::parse::token::InternedString;
 use syntax::visit;
+use syntax::util::small_vector::SmallVector;
 use ast_map;
 use log;
 
@@ -263,6 +264,7 @@ fn register_crate(&mut self,
 
         let cmeta = Rc::new( cstore::crate_metadata {
             name: name.to_string(),
+            local_path: RefCell::new(SmallVector::zero()),
             data: metadata,
             cnum_map: cnum_map,
             cnum: cnum,
@@ -520,12 +522,14 @@ fn process_item(&mut self, i: &ast::Item) {
 
                 match self.creader.extract_crate_info(i) {
                     Some(info) => {
-                        let (cnum, _, _) = self.creader.resolve_crate(&None,
+                        let (cnum, cmeta, _) = self.creader.resolve_crate(&None,
                                                               &info.ident,
                                                               &info.name,
                                                               None,
                                                               i.span,
                                                               PathKind::Crate);
+                        self.ast_map.with_path(i.id, |path|
+                            cmeta.update_local_path(path));
                         self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
                     }
                     None => ()
index 2a469ed69ef9a5b29b849ffda4b5f3c891c8a583..21d5dac7e5ddb13d97d88bfde4e3ae1914d55120 100644 (file)
@@ -24,7 +24,6 @@
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::expect;
-use syntax::parse::token;
 
 use std::collections::hash_map::HashMap;
 
@@ -89,11 +88,12 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
     let cdata = cstore.get_crate_data(def.krate);
     let path = decoder::get_item_path(&*cdata, def.node);
 
-    // FIXME #1920: This path is not always correct if the crate is not linked
-    // into the root namespace.
-    let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))];
-    r.push_all(&path);
-    r
+    cdata.with_local_path(|cpath| {
+        let mut r = Vec::with_capacity(cpath.len() + path.len());
+        r.push_all(cpath);
+        r.push_all(&path);
+        r
+    })
 }
 
 pub enum FoundAst<'ast> {
index 4941c932eadcc6336f2a81e705b132785a63ec57..08c05b768625b0687ddf4b376195825b0d2c5d7f 100644 (file)
 use flate::Bytes;
 use syntax::ast;
 use syntax::codemap;
+use syntax::parse::token;
 use syntax::parse::token::IdentInterner;
+use syntax::util::small_vector::SmallVector;
+use ast_map;
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
@@ -54,6 +57,7 @@ pub struct ImportedFileMap {
 
 pub struct crate_metadata {
     pub name: String,
+    pub local_path: RefCell<SmallVector<ast_map::PathElem>>,
     pub data: MetadataBlob,
     pub cnum_map: cnum_map,
     pub cnum: ast::CrateNum,
@@ -255,6 +259,30 @@ pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap)
             filemaps
         }
     }
+    pub fn with_local_path<T, F>(&self, f: F) -> T
+    where F: Fn(&[ast_map::PathElem]) -> T {
+        let cpath = self.local_path.borrow();
+        if cpath.is_empty() {
+            let name = ast_map::PathMod(token::intern(&self.name));
+            f(&[name])
+        } else {
+            f(cpath.as_slice())
+        }
+    }
+    pub fn update_local_path<'a, 'b>(&self, candidate: ast_map::PathElems<'a, 'b>) {
+        let mut cpath = self.local_path.borrow_mut();
+        let cap = cpath.len();
+        match cap {
+            0 => *cpath = candidate.collect(),
+            1 => (),
+            _ => {
+                let candidate: SmallVector<_> = candidate.collect();
+                if candidate.len() < cap {
+                    *cpath = candidate;
+                }
+            },
+        }
+    }
 }
 
 impl MetadataBlob {