Skip to content

Commit 8213e18

Browse files
committed
rustc: Simplify crate loading constraints
The previous code passed around a {name,version} pair everywhere, but this is better expressed as a CrateId. This patch changes these paths to store and pass around crate ids instead of these pairs of name/version. This also prepares the code to change the type of hash that is stored in crates.
1 parent 9b1be3d commit 8213e18

File tree

8 files changed

+160
-240
lines changed

8 files changed

+160
-240
lines changed

src/librustc/metadata/common.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ pub static tag_crate_deps: uint = 0x18;
7070
pub static tag_crate_dep: uint = 0x19;
7171

7272
pub static tag_crate_hash: uint = 0x1a;
73+
pub static tag_crate_crateid: uint = 0x1b;
7374

74-
pub static tag_parent_item: uint = 0x1b;
75+
pub static tag_parent_item: uint = 0x1c;
7576

76-
pub static tag_crate_dep_name: uint = 0x1c;
77-
pub static tag_crate_dep_hash: uint = 0x1d;
78-
pub static tag_crate_dep_vers: uint = 0x1e;
77+
pub static tag_crate_dep_crateid: uint = 0x1d;
78+
pub static tag_crate_dep_hash: uint = 0x1e;
7979

8080
pub static tag_mod_impl: uint = 0x1f;
8181

src/librustc/metadata/creader.rs

Lines changed: 94 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct cache_entry {
7979
cnum: ast::CrateNum,
8080
span: Span,
8181
hash: ~str,
82-
crateid: CrateId,
82+
crate_id: CrateId,
8383
}
8484

8585
fn dump_crates(crate_cache: &[cache_entry]) {
@@ -95,10 +95,10 @@ fn warn_if_multiple_versions(e: &mut Env,
9595
diag: @SpanHandler,
9696
crate_cache: &[cache_entry]) {
9797
if crate_cache.len() != 0u {
98-
let name = crate_cache[crate_cache.len() - 1].crateid.name.clone();
98+
let name = crate_cache[crate_cache.len() - 1].crate_id.name.clone();
9999

100100
let (matches, non_matches) = crate_cache.partitioned(|entry|
101-
name == entry.crateid.name);
101+
name == entry.crate_id.name);
102102

103103
assert!(!matches.is_empty());
104104

@@ -107,7 +107,7 @@ fn warn_if_multiple_versions(e: &mut Env,
107107
format!("using multiple versions of crate `{}`", name));
108108
for match_ in matches.iter() {
109109
diag.span_note(match_.span, "used here");
110-
loader::note_crateid_attr(diag, &match_.crateid);
110+
loader::note_crateid_attr(diag, &match_.crate_id);
111111
}
112112
}
113113

@@ -146,14 +146,9 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
146146
return;
147147
}
148148

149-
match extract_crate_info(i) {
149+
match extract_crate_info(e, i) {
150150
Some(info) => {
151-
let cnum = resolve_crate(e,
152-
None,
153-
info.ident.clone(),
154-
info.name.clone(),
155-
info.version.clone(),
156-
~"",
151+
let cnum = resolve_crate(e, None, info.ident, &info.crate_id, "",
157152
i.span);
158153
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
159154
}
@@ -163,38 +158,33 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
163158

164159
struct CrateInfo {
165160
ident: ~str,
166-
name: ~str,
167-
version: ~str,
161+
crate_id: CrateId,
168162
id: ast::NodeId,
169163
}
170164

171-
fn extract_crate_info(i: &ast::ViewItem) -> Option<CrateInfo> {
165+
fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
172166
match i.node {
173167
ast::ViewItemExternMod(ident, ref path_opt, id) => {
174168
let ident = token::get_ident(ident);
175169
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
176170
ident, path_opt);
177-
let (name, version) = match *path_opt {
171+
let crate_id = match *path_opt {
178172
Some((ref path_str, _)) => {
179173
let crateid: Option<CrateId> = from_str(path_str.get());
180174
match crateid {
181-
None => (~"", ~""),
182-
Some(crateid) => {
183-
let version = match crateid.version {
184-
None => ~"",
185-
Some(ref ver) => ver.to_str(),
186-
};
187-
(crateid.name.to_str(), version)
175+
None => {
176+
e.sess.span_err(i.span, "malformed crate id");
177+
return None
188178
}
179+
Some(id) => id
189180
}
190181
}
191-
None => (ident.get().to_str(), ~""),
182+
None => from_str(ident.get().to_str()).unwrap()
192183
};
193184
Some(CrateInfo {
194-
ident: ident.get().to_str(),
195-
name: name,
196-
version: version,
197-
id: id,
185+
ident: ident.get().to_str(),
186+
crate_id: crate_id,
187+
id: id,
198188
})
199189
}
200190
_ => None
@@ -285,100 +275,93 @@ fn visit_item(e: &Env, i: &ast::Item) {
285275
}
286276
}
287277

288-
fn existing_match(e: &Env, name: &str, version: &str, hash: &str) -> Option<ast::CrateNum> {
278+
fn existing_match(e: &Env, crate_id: &CrateId,
279+
hash: &str) -> Option<ast::CrateNum> {
289280
let crate_cache = e.crate_cache.borrow();
290281
for c in crate_cache.get().iter() {
291-
let crateid_version = match c.crateid.version {
292-
None => ~"0.0",
293-
Some(ref ver) => ver.to_str(),
294-
};
295-
if (name.is_empty() || name == c.crateid.name) &&
296-
(version.is_empty() || version == crateid_version) &&
297-
(hash.is_empty() || hash == c.hash) {
298-
return Some(c.cnum);
282+
if crate_id.matches(&c.crate_id) &&
283+
(hash.is_empty() || hash == c.hash.as_slice()) {
284+
return Some(c.cnum)
299285
}
300286
}
301287
None
302288
}
303289

304290
fn resolve_crate(e: &mut Env,
305-
root_ident: Option<~str>,
306-
ident: ~str,
307-
name: ~str,
308-
version: ~str,
309-
hash: ~str,
291+
root_ident: Option<&str>,
292+
ident: &str,
293+
crate_id: &CrateId,
294+
hash: &str,
310295
span: Span)
311296
-> ast::CrateNum {
312-
match existing_match(e, name, version, hash) {
313-
None => {
314-
let load_ctxt = loader::Context {
315-
sess: e.sess,
316-
span: span,
317-
ident: ident,
318-
name: name,
319-
version: version,
320-
hash: hash,
321-
os: e.os,
322-
intr: e.intr
323-
};
324-
let loader::Library {
325-
dylib, rlib, metadata
326-
} = load_ctxt.load_library_crate(root_ident.clone());
327-
328-
let attrs = decoder::get_crate_attributes(metadata.as_slice());
329-
let crateid = attr::find_crateid(attrs).unwrap();
330-
let hash = decoder::get_crate_hash(metadata.as_slice());
331-
332-
// Claim this crate number and cache it
333-
let cnum = e.next_crate_num;
334-
{
335-
let mut crate_cache = e.crate_cache.borrow_mut();
336-
crate_cache.get().push(cache_entry {
337-
cnum: cnum,
297+
match existing_match(e, crate_id, hash) {
298+
None => {
299+
let load_ctxt = loader::Context {
300+
sess: e.sess,
338301
span: span,
302+
ident: ident,
303+
crate_id: crate_id,
339304
hash: hash,
340-
crateid: crateid,
341-
});
342-
}
343-
e.next_crate_num += 1;
344-
345-
// Maintain a reference to the top most crate.
346-
let root_crate = match root_ident {
347-
Some(c) => c,
348-
None => load_ctxt.ident.clone()
349-
};
305+
os: e.os,
306+
intr: e.intr
307+
};
308+
let loader::Library {
309+
dylib, rlib, metadata
310+
} = load_ctxt.load_library_crate(root_ident);
311+
312+
let crate_id = decoder::get_crate_id(metadata.as_slice());
313+
let hash = decoder::get_crate_hash(metadata.as_slice());
314+
315+
// Claim this crate number and cache it
316+
let cnum = e.next_crate_num;
317+
{
318+
let mut crate_cache = e.crate_cache.borrow_mut();
319+
crate_cache.get().push(cache_entry {
320+
cnum: cnum,
321+
span: span,
322+
hash: hash,
323+
crate_id: crate_id,
324+
});
325+
}
326+
e.next_crate_num += 1;
350327

351-
// Now resolve the crates referenced by this crate
352-
let cnum_map = resolve_crate_deps(e,
353-
Some(root_crate),
354-
metadata.as_slice(),
355-
span);
328+
// Maintain a reference to the top most crate.
329+
let root_crate = match root_ident {
330+
Some(c) => c,
331+
None => load_ctxt.ident.clone()
332+
};
356333

357-
let cmeta = @cstore::crate_metadata {
358-
name: load_ctxt.name,
359-
data: metadata,
360-
cnum_map: cnum_map,
361-
cnum: cnum
362-
};
334+
// Now resolve the crates referenced by this crate
335+
let cnum_map = resolve_crate_deps(e,
336+
Some(root_crate),
337+
metadata.as_slice(),
338+
span);
339+
340+
let cmeta = @cstore::crate_metadata {
341+
name: load_ctxt.crate_id.name.to_owned(),
342+
data: metadata,
343+
cnum_map: cnum_map,
344+
cnum: cnum
345+
};
363346

364-
let cstore = e.sess.cstore;
365-
cstore.set_crate_data(cnum, cmeta);
366-
cstore.add_used_crate_source(cstore::CrateSource {
367-
dylib: dylib,
368-
rlib: rlib,
369-
cnum: cnum,
370-
});
371-
return cnum;
372-
}
373-
Some(cnum) => {
374-
return cnum;
375-
}
347+
let cstore = e.sess.cstore;
348+
cstore.set_crate_data(cnum, cmeta);
349+
cstore.add_used_crate_source(cstore::CrateSource {
350+
dylib: dylib,
351+
rlib: rlib,
352+
cnum: cnum,
353+
});
354+
return cnum;
355+
}
356+
Some(cnum) => {
357+
return cnum;
358+
}
376359
}
377360
}
378361

379362
// Go through the crate metadata and load any crates that it references
380363
fn resolve_crate_deps(e: &mut Env,
381-
root_ident: Option<~str>,
364+
root_ident: Option<&str>,
382365
cdata: &[u8], span : Span)
383366
-> cstore::cnum_map {
384367
debug!("resolving deps of external crate");
@@ -388,31 +371,13 @@ fn resolve_crate_deps(e: &mut Env,
388371
let r = decoder::get_crate_deps(cdata);
389372
for dep in r.iter() {
390373
let extrn_cnum = dep.cnum;
391-
let cname_str = token::get_ident(dep.name);
392-
debug!("resolving dep crate {} ver: {} hash: {}",
393-
cname_str, dep.vers, dep.hash);
394-
match existing_match(e,
395-
cname_str.get(),
396-
dep.vers,
397-
dep.hash) {
398-
Some(local_cnum) => {
399-
debug!("already have it");
400-
// We've already seen this crate
401-
cnum_map.insert(extrn_cnum, local_cnum);
402-
}
403-
None => {
404-
debug!("need to load it");
405-
// This is a new one so we've got to load it
406-
let local_cnum = resolve_crate(e,
407-
root_ident.clone(),
408-
cname_str.get().to_str(),
409-
cname_str.get().to_str(),
410-
dep.vers.clone(),
411-
dep.hash.clone(),
412-
span);
413-
cnum_map.insert(extrn_cnum, local_cnum);
414-
}
415-
}
374+
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
375+
let local_cnum = resolve_crate(e, root_ident,
376+
dep.crate_id.name.as_slice(),
377+
&dep.crate_id,
378+
dep.hash,
379+
span);
380+
cnum_map.insert(extrn_cnum, local_cnum);
416381
}
417382
return @RefCell::new(cnum_map);
418383
}
@@ -439,14 +404,9 @@ impl Loader {
439404

440405
impl CrateLoader for Loader {
441406
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
442-
let info = extract_crate_info(krate).unwrap();
443-
let cnum = resolve_crate(&mut self.env,
444-
None,
445-
info.ident.clone(),
446-
info.name.clone(),
447-
info.version.clone(),
448-
~"",
449-
krate.span);
407+
let info = extract_crate_info(&self.env, krate).unwrap();
408+
let cnum = resolve_crate(&mut self.env, None, info.ident,
409+
&info.crate_id, "", krate.span);
450410
let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
451411
MacroCrate {
452412
lib: library.dylib,

0 commit comments

Comments
 (0)