@@ -34,6 +34,7 @@ fn read_crates(sess: session::session, crate: ast::crate) {
3434type cache_entry = {
3535 cnum: int,
3636 span: span,
37+ hash: str,
3738 metas: @[ @ast:: meta_item]
3839} ;
3940
@@ -77,7 +78,7 @@ type env = @{sess: session::session,
7778fn visit_view_item ( e : env , i : @ast:: view_item ) {
7879 alt i. node {
7980 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 ) ;
8182 cstore:: add_use_stmt_cnum ( e. sess . cstore , id, cnum) ;
8283 }
8384 _ { }
@@ -140,9 +141,14 @@ fn list_file_metadata(sess: session::session, path: str, out: io::writer) {
140141 }
141142}
142143
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 {
144146 let attrs = decoder:: get_crate_attributes ( crate_data) ;
145147 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+ }
146152 metadata_matches ( linkage_metas, metas)
147153}
148154
@@ -194,30 +200,30 @@ fn crate_name_from_metas(metas: [@ast::meta_item]) -> str {
194200}
195201
196202fn find_library_crate ( sess : session:: session , span : span ,
197- metas : [ @ast:: meta_item ] )
203+ metas : [ @ast:: meta_item ] , hash : str )
198204 -> option < { ident: str , data : @[ u8 ] } > {
199205
200206 attr:: require_unique_names ( sess. diagnostic ( ) , metas) ;
201207 let metas = metas;
202- let crate_name = crate_name_from_metas ( metas) ;
203208
204209 let nn = default_native_lib_naming ( sess, sess. opts . static ) ;
205210 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 ) ;
208213 if x != none || sess. opts . static { ret x; }
209214 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 ,
211216 sess. filesearch ) ;
212217}
213218
214219fn find_library_crate_aux ( sess : session:: session ,
215220 span : span ,
216221 nn : { prefix : str , suffix : str } ,
217- crate_name : str ,
218222 metas : [ @ast:: meta_item ] ,
223+ hash : str ,
219224 filesearch : filesearch:: filesearch ) ->
220225 option < { ident: str , data : @[ u8 ] } > {
226+ let crate_name = crate_name_from_metas ( metas) ;
221227 let prefix: str = nn. prefix + crate_name + "-" ;
222228 let suffix: str = nn. suffix ;
223229
@@ -233,7 +239,7 @@ fn find_library_crate_aux(sess: session::session,
233239 #debug ( "%s is a candidate" , path) ;
234240 alt get_metadata_section ( sess, path) {
235241 option:: some ( cvec) {
236- if !crate_matches ( cvec, metas) {
242+ if !crate_matches ( cvec, metas, hash ) {
237243 #debug ( "skipping %s, metadata doesn't match" , path) ;
238244 option:: none
239245 } else {
@@ -302,11 +308,11 @@ fn get_metadata_section(sess: session::session,
302308}
303309
304310fn load_library_crate ( sess : session:: session , ident : ast:: ident , span : span ,
305- metas : [ @ast:: meta_item ] )
311+ metas : [ @ast:: meta_item ] , hash : str )
306312 -> { ident: str , data: @[ u8] } {
307313
308314
309- alt find_library_crate ( sess, span, metas) {
315+ alt find_library_crate ( sess, span, metas, hash ) {
310316 some ( t) { ret t; }
311317 none {
312318 sess. span_fatal ( span, #fmt[ "can't find crate for '%s'" , ident] ) ;
@@ -329,32 +335,36 @@ fn metas_with_ident(ident: ast::ident,
329335 metas_with ( ident, "name" , metas)
330336}
331337
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 > {
333340 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)
335343 } ;
336344
337345 maybe_entry. map { |c| c. cnum }
338346}
339347
340348fn 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 {
342350 let metas = metas_with_ident ( ident, metas) ;
343351
344- alt existing_match ( e, metas) {
352+ alt existing_match ( e, metas, hash ) {
345353 none {
346354 let cinfo =
347- load_library_crate ( e. sess , ident, span, metas) ;
355+ load_library_crate ( e. sess , ident, span, metas, hash ) ;
348356
349357 let cfilename = cinfo. ident ;
350358 let cdata = cinfo. data ;
351359
352360 let attrs = decoder:: get_crate_attributes ( cdata) ;
353361 let linkage_metas = attr:: find_linkage_metas ( attrs) ;
362+ let hash = decoder:: get_crate_hash ( cdata) ;
354363
355364 // Claim this crate number and cache it
356365 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} ] ;
358368 e. next_crate_num += 1 ;
359369
360370 // Now resolve the crates referenced by this crate
@@ -387,12 +397,10 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map {
387397 for decoder:: get_crate_deps( cdata) . each { |dep|
388398 let extrn_cnum = dep. cnum;
389399 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 ) {
396404 some ( local_cnum) {
397405 #debug ( "already have it" ) ;
398406 // We've already seen this crate
@@ -403,7 +411,8 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map {
403411 // This is a new one so we've got to load it
404412 // FIXME: Need better error reporting than just a bogus span
405413 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) ;
407416 cnum_map. insert ( extrn_cnum, local_cnum) ;
408417 }
409418 }
0 commit comments