@@ -34,6 +34,7 @@ fn read_crates(sess: session::session, crate: ast::crate) {
34
34
type cache_entry = {
35
35
cnum: int,
36
36
span: span,
37
+ hash: str,
37
38
metas: @[ @ast:: meta_item]
38
39
} ;
39
40
@@ -77,7 +78,7 @@ type env = @{sess: session::session,
77
78
fn visit_view_item ( e : env , i : @ast:: view_item ) {
78
79
alt i. node {
79
80
ast:: view_item_use ( ident, meta_items, id) {
80
- let cnum = resolve_crate ( e, ident, meta_items, i. span ) ;
81
+ let cnum = resolve_crate ( e, ident, meta_items, "" , i. span ) ;
81
82
cstore:: add_use_stmt_cnum ( e. sess . cstore , id, cnum) ;
82
83
}
83
84
_ { }
@@ -140,9 +141,14 @@ fn list_file_metadata(sess: session::session, path: str, out: io::writer) {
140
141
}
141
142
}
142
143
143
- fn crate_matches ( crate_data : @[ u8 ] , metas : [ @ast:: meta_item ] ) -> bool {
144
+ fn crate_matches ( crate_data : @[ u8 ] , metas : [ @ast:: meta_item ] , hash : str ) ->
145
+ bool {
144
146
let attrs = decoder:: get_crate_attributes ( crate_data) ;
145
147
let linkage_metas = attr:: find_linkage_metas ( attrs) ;
148
+ if hash. is_not_empty ( ) {
149
+ let chash = decoder:: get_crate_hash ( crate_data) ;
150
+ if chash != hash { ret false ; }
151
+ }
146
152
metadata_matches ( linkage_metas, metas)
147
153
}
148
154
@@ -194,30 +200,30 @@ fn crate_name_from_metas(metas: [@ast::meta_item]) -> str {
194
200
}
195
201
196
202
fn find_library_crate ( sess : session:: session , span : span ,
197
- metas : [ @ast:: meta_item ] )
203
+ metas : [ @ast:: meta_item ] , hash : str )
198
204
-> option < { ident: str , data : @[ u8 ] } > {
199
205
200
206
attr:: require_unique_names ( sess. diagnostic ( ) , metas) ;
201
207
let metas = metas;
202
- let crate_name = crate_name_from_metas ( metas) ;
203
208
204
209
let nn = default_native_lib_naming ( sess, sess. opts . static ) ;
205
210
let x =
206
- find_library_crate_aux ( sess, span, nn, crate_name ,
207
- metas, sess. filesearch ) ;
211
+ find_library_crate_aux ( sess, span, nn,
212
+ metas, hash , sess. filesearch ) ;
208
213
if x != none || sess. opts . static { ret x; }
209
214
let nn2 = default_native_lib_naming ( sess, true ) ;
210
- ret find_library_crate_aux ( sess, span, nn2, crate_name , metas ,
215
+ ret find_library_crate_aux ( sess, span, nn2, metas , hash ,
211
216
sess. filesearch ) ;
212
217
}
213
218
214
219
fn find_library_crate_aux ( sess : session:: session ,
215
220
span : span ,
216
221
nn : { prefix : str , suffix : str } ,
217
- crate_name : str ,
218
222
metas : [ @ast:: meta_item ] ,
223
+ hash : str ,
219
224
filesearch : filesearch:: filesearch ) ->
220
225
option < { ident: str , data : @[ u8 ] } > {
226
+ let crate_name = crate_name_from_metas ( metas) ;
221
227
let prefix: str = nn. prefix + crate_name + "-" ;
222
228
let suffix: str = nn. suffix ;
223
229
@@ -233,7 +239,7 @@ fn find_library_crate_aux(sess: session::session,
233
239
#debug ( "%s is a candidate" , path) ;
234
240
alt get_metadata_section ( sess, path) {
235
241
option:: some ( cvec) {
236
- if !crate_matches ( cvec, metas) {
242
+ if !crate_matches ( cvec, metas, hash ) {
237
243
#debug ( "skipping %s, metadata doesn't match" , path) ;
238
244
option:: none
239
245
} else {
@@ -302,11 +308,11 @@ fn get_metadata_section(sess: session::session,
302
308
}
303
309
304
310
fn load_library_crate ( sess : session:: session , ident : ast:: ident , span : span ,
305
- metas : [ @ast:: meta_item ] )
311
+ metas : [ @ast:: meta_item ] , hash : str )
306
312
-> { ident: str , data: @[ u8] } {
307
313
308
314
309
- alt find_library_crate ( sess, span, metas) {
315
+ alt find_library_crate ( sess, span, metas, hash ) {
310
316
some ( t) { ret t; }
311
317
none {
312
318
sess. span_fatal ( span, #fmt[ "can't find crate for '%s'" , ident] ) ;
@@ -329,32 +335,36 @@ fn metas_with_ident(ident: ast::ident,
329
335
metas_with ( ident, "name" , metas)
330
336
}
331
337
332
- fn existing_match ( e : env , metas : [ @ast:: meta_item ] ) -> option < int > {
338
+ fn existing_match ( e : env , metas : [ @ast:: meta_item ] , hash : str ) ->
339
+ option < int > {
333
340
let maybe_entry = e. crate_cache . find { |c|
334
- metadata_matches ( * c. metas , metas)
341
+ metadata_matches ( * c. metas , metas) &&
342
+ ( hash. is_empty ( ) || c. hash == hash)
335
343
} ;
336
344
337
345
maybe_entry. map { |c| c. cnum }
338
346
}
339
347
340
348
fn resolve_crate ( e : env , ident : ast:: ident , metas : [ @ast:: meta_item ] ,
341
- span : span ) -> ast:: crate_num {
349
+ hash : str , span : span ) -> ast:: crate_num {
342
350
let metas = metas_with_ident ( ident, metas) ;
343
351
344
- alt existing_match ( e, metas) {
352
+ alt existing_match ( e, metas, hash ) {
345
353
none {
346
354
let cinfo =
347
- load_library_crate ( e. sess , ident, span, metas) ;
355
+ load_library_crate ( e. sess , ident, span, metas, hash ) ;
348
356
349
357
let cfilename = cinfo. ident ;
350
358
let cdata = cinfo. data ;
351
359
352
360
let attrs = decoder:: get_crate_attributes ( cdata) ;
353
361
let linkage_metas = attr:: find_linkage_metas ( attrs) ;
362
+ let hash = decoder:: get_crate_hash ( cdata) ;
354
363
355
364
// Claim this crate number and cache it
356
365
let cnum = e. next_crate_num ;
357
- e. crate_cache += [ { cnum: cnum, span: span, metas: @linkage_metas} ] ;
366
+ e. crate_cache += [ { cnum: cnum, span: span,
367
+ hash: hash, metas: @linkage_metas} ] ;
358
368
e. next_crate_num += 1 ;
359
369
360
370
// Now resolve the crates referenced by this crate
@@ -387,12 +397,10 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map {
387
397
for decoder:: get_crate_deps( cdata) . each { |dep|
388
398
let extrn_cnum = dep. cnum;
389
399
let cname = dep. name ;
390
- let cvers = dep. vers ;
391
- // FIXME: We really need to know the linkage metas of our transitive
392
- // dependencies in order to resolve them correctly.
393
- let cmetas = metas_with ( cvers, "vers" , [ ] ) ;
394
- #debug ( "resolving dep %s ver: %s" , cname, dep. vers ) ;
395
- alt existing_match ( e, metas_with_ident ( cname, cmetas) ) {
400
+ let cmetas = metas_with ( dep. vers , "vers" , [ ] ) ;
401
+ #debug ( "resolving dep crate %s ver: %s hash: %s" ,
402
+ dep. name , dep. vers , dep. hash ) ;
403
+ alt existing_match ( e, metas_with_ident ( cname, cmetas) , dep. hash ) {
396
404
some ( local_cnum) {
397
405
#debug ( "already have it" ) ;
398
406
// We've already seen this crate
@@ -403,7 +411,8 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map {
403
411
// This is a new one so we've got to load it
404
412
// FIXME: Need better error reporting than just a bogus span
405
413
let fake_span = ast_util:: dummy_sp ( ) ;
406
- let local_cnum = resolve_crate ( e, cname, cmetas, fake_span) ;
414
+ let local_cnum =
415
+ resolve_crate ( e, cname, cmetas, dep. hash , fake_span) ;
407
416
cnum_map. insert ( extrn_cnum, local_cnum) ;
408
417
}
409
418
}
0 commit comments