Skip to content

Commit 2b41246

Browse files
committed
Store and use crate-local paths to extern crates
1 parent a98fd11 commit 2b41246

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

src/librustc/metadata/creader.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use syntax::codemap::{self, Span, mk_sp, Pos};
3434
use syntax::parse;
3535
use syntax::parse::token::InternedString;
3636
use syntax::visit;
37+
use syntax::util::small_vector::SmallVector;
3738
use ast_map;
3839
use log;
3940

@@ -263,6 +264,7 @@ impl<'a> CrateReader<'a> {
263264

264265
let cmeta = Rc::new( cstore::crate_metadata {
265266
name: name.to_string(),
267+
local_path: RefCell::new(SmallVector::zero()),
266268
data: metadata,
267269
cnum_map: cnum_map,
268270
cnum: cnum,
@@ -520,12 +522,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
520522

521523
match self.creader.extract_crate_info(i) {
522524
Some(info) => {
523-
let (cnum, _, _) = self.creader.resolve_crate(&None,
525+
let (cnum, cmeta, _) = self.creader.resolve_crate(&None,
524526
&info.ident,
525527
&info.name,
526528
None,
527529
i.span,
528530
PathKind::Crate);
531+
self.ast_map.with_path(i.id, |path|
532+
cmeta.update_local_path(path));
529533
self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
530534
}
531535
None => ()

src/librustc/metadata/csearch.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use syntax::ast;
2424
use syntax::attr;
2525
use syntax::attr::AttrMetaMethods;
2626
use syntax::diagnostic::expect;
27-
use syntax::parse::token;
2827

2928
use std::collections::hash_map::HashMap;
3029

@@ -89,11 +88,12 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
8988
let cdata = cstore.get_crate_data(def.krate);
9089
let path = decoder::get_item_path(&*cdata, def.node);
9190

92-
// FIXME #1920: This path is not always correct if the crate is not linked
93-
// into the root namespace.
94-
let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))];
95-
r.push_all(&path);
96-
r
91+
cdata.with_local_path(|cpath| {
92+
let mut r = Vec::with_capacity(cpath.len() + path.len());
93+
r.push_all(cpath);
94+
r.push_all(&path);
95+
r
96+
})
9797
}
9898

9999
pub enum FoundAst<'ast> {

src/librustc/metadata/cstore.rs

+28
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ use std::path::PathBuf;
2828
use flate::Bytes;
2929
use syntax::ast;
3030
use syntax::codemap;
31+
use syntax::parse::token;
3132
use syntax::parse::token::IdentInterner;
33+
use syntax::util::small_vector::SmallVector;
34+
use ast_map;
3235

3336
// A map from external crate numbers (as decoded from some crate file) to
3437
// local crate numbers (as generated during this session). Each external
@@ -54,6 +57,7 @@ pub struct ImportedFileMap {
5457

5558
pub struct crate_metadata {
5659
pub name: String,
60+
pub local_path: RefCell<SmallVector<ast_map::PathElem>>,
5761
pub data: MetadataBlob,
5862
pub cnum_map: cnum_map,
5963
pub cnum: ast::CrateNum,
@@ -255,6 +259,30 @@ impl crate_metadata {
255259
filemaps
256260
}
257261
}
262+
pub fn with_local_path<T, F>(&self, f: F) -> T
263+
where F: Fn(&[ast_map::PathElem]) -> T {
264+
let cpath = self.local_path.borrow();
265+
if cpath.is_empty() {
266+
let name = ast_map::PathMod(token::intern(&self.name));
267+
f(&[name])
268+
} else {
269+
f(cpath.as_slice())
270+
}
271+
}
272+
pub fn update_local_path<'a, 'b>(&self, candidate: ast_map::PathElems<'a, 'b>) {
273+
let mut cpath = self.local_path.borrow_mut();
274+
let cap = cpath.len();
275+
match cap {
276+
0 => *cpath = candidate.collect(),
277+
1 => (),
278+
_ => {
279+
let candidate: SmallVector<_> = candidate.collect();
280+
if candidate.len() < cap {
281+
*cpath = candidate;
282+
}
283+
},
284+
}
285+
}
258286
}
259287

260288
impl MetadataBlob {

0 commit comments

Comments
 (0)