@@ -18,6 +18,7 @@ use driver::{driver, session};
18
18
use driver:: session:: Session ;
19
19
use metadata:: csearch;
20
20
use metadata:: cstore;
21
+ use metadata:: cstore:: CStore ;
21
22
use metadata:: decoder;
22
23
use metadata:: loader;
23
24
use metadata:: loader:: Os ;
@@ -38,6 +39,13 @@ use syntax::parse::token;
38
39
use syntax:: crateid:: CrateId ;
39
40
use syntax:: visit;
40
41
42
+ struct Env < ' a > {
43
+ sess : & ' a Session ,
44
+ os : loader:: Os ,
45
+ next_crate_num : ast:: CrateNum ,
46
+ intr : Rc < IdentInterner >
47
+ }
48
+
41
49
// Traverses an AST, reading all the information about use'd crates and extern
42
50
// libraries necessary for later resolving, typechecking, linking, etc.
43
51
pub fn read_crates ( sess : & Session ,
@@ -47,16 +55,13 @@ pub fn read_crates(sess: &Session,
47
55
let mut e = Env {
48
56
sess : sess,
49
57
os : os,
50
- crate_cache : @RefCell :: new ( Vec :: new ( ) ) ,
51
- next_crate_num : 1 ,
58
+ next_crate_num : sess. cstore . next_crate_num ( ) ,
52
59
intr : intr
53
60
} ;
54
61
visit_crate ( & e, krate) ;
55
62
visit:: walk_crate ( & mut e, krate, ( ) ) ;
56
- dump_crates ( e. crate_cache . borrow ( ) . as_slice ( ) ) ;
57
- warn_if_multiple_versions ( & mut e,
58
- sess. diagnostic ( ) ,
59
- e. crate_cache . borrow ( ) . as_slice ( ) ) ;
63
+ dump_crates ( & sess. cstore ) ;
64
+ warn_if_multiple_versions ( sess. diagnostic ( ) , & sess. cstore )
60
65
}
61
66
62
67
impl < ' a > visit:: Visitor < ( ) > for Env < ' a > {
@@ -70,55 +75,36 @@ impl<'a> visit::Visitor<()> for Env<'a> {
70
75
}
71
76
}
72
77
73
- #[ deriving( Clone ) ]
74
- struct cache_entry {
75
- cnum : ast:: CrateNum ,
76
- span : Span ,
77
- hash : Svh ,
78
- crate_id : CrateId ,
79
- }
80
-
81
- fn dump_crates ( crate_cache : & [ cache_entry ] ) {
78
+ fn dump_crates ( cstore : & CStore ) {
82
79
debug ! ( "resolved crates:" ) ;
83
- for entry in crate_cache . iter ( ) {
84
- debug ! ( "cnum : {:? }" , entry . cnum ) ;
85
- debug ! ( "span : {:? }" , entry . span ) ;
86
- debug ! ( "hash: {:? }" , entry . hash) ;
87
- }
80
+ cstore . iter_crate_data ( |_ , data| {
81
+ debug ! ( "crate_id : {}" , data . crate_id ( ) ) ;
82
+ debug ! ( " cnum : {}" , data . cnum ) ;
83
+ debug ! ( " hash: {}" , data . hash( ) ) ;
84
+ } )
88
85
}
89
86
90
- fn warn_if_multiple_versions ( e : & mut Env ,
91
- diag : & SpanHandler ,
92
- crate_cache : & [ cache_entry ] ) {
93
- if crate_cache. len ( ) != 0 u {
94
- let name = crate_cache[ crate_cache. len ( ) - 1 ] . crate_id . name . clone ( ) ;
95
-
96
- let ( matches, non_matches) = crate_cache. partitioned ( |entry|
97
- name == entry. crate_id . name ) ;
87
+ fn warn_if_multiple_versions ( diag : & SpanHandler , cstore : & CStore ) {
88
+ let mut map = HashMap :: new ( ) ;
98
89
99
- assert ! ( !matches. is_empty( ) ) ;
90
+ cstore. iter_crate_data ( |cnum, data| {
91
+ let crateid = data. crate_id ( ) ;
92
+ let key = ( crateid. name . clone ( ) , crateid. path . clone ( ) ) ;
93
+ map. find_or_insert_with ( key, |_| Vec :: new ( ) ) . push ( cnum) ;
94
+ } ) ;
100
95
101
- if matches. len ( ) != 1 u {
102
- diag. handler ( ) . warn (
103
- format ! ( "using multiple versions of crate `{}`" , name) ) ;
104
- for match_ in matches. iter ( ) {
105
- diag. span_note ( match_. span , "used here" ) ;
106
- loader:: note_crateid_attr ( diag, & match_. crate_id ) ;
107
- }
96
+ for ( ( name, _) , dupes) in map. move_iter ( ) {
97
+ if dupes. len ( ) == 1 { continue }
98
+ diag. handler ( ) . warn (
99
+ format ! ( "using multiple versions of crate `{}`" , name) ) ;
100
+ for dupe in dupes. move_iter ( ) {
101
+ let data = cstore. get_crate_data ( dupe) ;
102
+ diag. span_note ( data. span , "used here" ) ;
103
+ loader:: note_crateid_attr ( diag, & data. crate_id ( ) ) ;
108
104
}
109
-
110
- warn_if_multiple_versions ( e, diag, non_matches) ;
111
105
}
112
106
}
113
107
114
- struct Env < ' a > {
115
- sess : & ' a Session ,
116
- os : loader:: Os ,
117
- crate_cache : @RefCell < Vec < cache_entry > > ,
118
- next_crate_num : ast:: CrateNum ,
119
- intr : Rc < IdentInterner >
120
- }
121
-
122
108
fn visit_crate ( e : & Env , c : & ast:: Crate ) {
123
109
for a in c. attrs . iter ( ) . filter ( |m| m. name ( ) . equiv ( & ( "link_args" ) ) ) {
124
110
match a. value_str ( ) {
@@ -269,14 +255,18 @@ fn visit_item(e: &Env, i: &ast::Item) {
269
255
270
256
fn existing_match ( e : & Env , crate_id : & CrateId ,
271
257
hash : Option < & Svh > ) -> Option < ast:: CrateNum > {
272
- for c in e. crate_cache . borrow ( ) . iter ( ) {
273
- if !crate_id. matches ( & c. crate_id ) { continue }
274
- match hash {
275
- Some ( hash) if * hash != c. hash => { }
276
- Some ( ..) | None => return Some ( c. cnum )
258
+ let mut ret = None ;
259
+ e. sess . cstore . iter_crate_data ( |cnum, data| {
260
+ let other_id = data. crate_id ( ) ;
261
+ if crate_id. matches ( & other_id) {
262
+ let other_hash = data. hash ( ) ;
263
+ match hash {
264
+ Some ( hash) if * hash != other_hash => { }
265
+ Some ( ..) | None => { ret = Some ( cnum) ; }
266
+ }
277
267
}
278
- }
279
- None
268
+ } ) ;
269
+ return ret ;
280
270
}
281
271
282
272
fn resolve_crate < ' a > ( e : & mut Env ,
@@ -304,17 +294,8 @@ fn resolve_crate<'a>(e: &mut Env,
304
294
dylib, rlib, metadata
305
295
} = load_ctxt. load_library_crate ( root) ;
306
296
307
- let crate_id = decoder:: get_crate_id ( metadata. as_slice ( ) ) ;
308
- let hash = decoder:: get_crate_hash ( metadata. as_slice ( ) ) ;
309
-
310
297
// Claim this crate number and cache it
311
298
let cnum = e. next_crate_num ;
312
- e. crate_cache . borrow_mut ( ) . push ( cache_entry {
313
- cnum : cnum,
314
- span : span,
315
- hash : hash,
316
- crate_id : crate_id,
317
- } ) ;
318
299
e. next_crate_num += 1 ;
319
300
320
301
// Stash paths for top-most crate locally if necessary.
@@ -331,16 +312,15 @@ fn resolve_crate<'a>(e: &mut Env,
331
312
let root = if root. is_some ( ) { root } else { & crate_paths } ;
332
313
333
314
// Now resolve the crates referenced by this crate
334
- let cnum_map = resolve_crate_deps ( e,
335
- root,
336
- metadata. as_slice ( ) ,
337
- span) ;
315
+ let cnum_map = resolve_crate_deps ( e, root, metadata. as_slice ( ) ,
316
+ span) ;
338
317
339
318
let cmeta = @cstore:: crate_metadata {
340
319
name : load_ctxt. crate_id . name . to_owned ( ) ,
341
320
data : metadata,
342
321
cnum_map : cnum_map,
343
- cnum : cnum
322
+ cnum : cnum,
323
+ span : span,
344
324
} ;
345
325
346
326
e. sess . cstore . set_crate_data ( cnum, cmeta) ;
@@ -390,8 +370,7 @@ impl<'a> Loader<'a> {
390
370
env : Env {
391
371
sess : sess,
392
372
os : os,
393
- crate_cache : @RefCell :: new ( Vec :: new ( ) ) ,
394
- next_crate_num : 1 ,
373
+ next_crate_num : sess. cstore . next_crate_num ( ) ,
395
374
intr : token:: get_ident_interner ( ) ,
396
375
}
397
376
}
@@ -406,7 +385,7 @@ impl<'a> CrateLoader for Loader<'a> {
406
385
let library = self . env . sess . cstore . get_used_crate_source ( cnum) . unwrap ( ) ;
407
386
MacroCrate {
408
387
lib : library. dylib ,
409
- cnum : cnum
388
+ cnum : cnum,
410
389
}
411
390
}
412
391
0 commit comments