@@ -143,6 +143,11 @@ impl PMDSource {
143143 }
144144}
145145
146+ enum LoadResult {
147+ Previous ( ast:: CrateNum ) ,
148+ Loaded ( loader:: Library ) ,
149+ }
150+
146151impl < ' a > CrateReader < ' a > {
147152 pub fn new ( sess : & ' a Session ,
148153 cstore : & ' a CStore ,
@@ -358,12 +363,8 @@ impl<'a> CrateReader<'a> {
358363 kind : PathKind ,
359364 explicitly_linked : bool )
360365 -> ( ast:: CrateNum , Rc < cstore:: crate_metadata > , cstore:: CrateSource ) {
361- enum LookupResult {
362- Previous ( ast:: CrateNum ) ,
363- Loaded ( loader:: Library ) ,
364- }
365366 let result = match self . existing_match ( name, hash, kind) {
366- Some ( cnum) => LookupResult :: Previous ( cnum) ,
367+ Some ( cnum) => LoadResult :: Previous ( cnum) ,
367368 None => {
368369 let mut load_ctxt = loader:: Context {
369370 sess : self . sess ,
@@ -380,40 +381,59 @@ impl<'a> CrateReader<'a> {
380381 rejected_via_kind : vec ! ( ) ,
381382 should_match_name : true ,
382383 } ;
383- let library = load_ctxt. load_library_crate ( ) ;
384-
385- // In the case that we're loading a crate, but not matching
386- // against a hash, we could load a crate which has the same hash
387- // as an already loaded crate. If this is the case prevent
388- // duplicates by just using the first crate.
389- let meta_hash = decoder:: get_crate_hash ( library. metadata
390- . as_slice ( ) ) ;
391- let mut result = LookupResult :: Loaded ( library) ;
392- self . cstore . iter_crate_data ( |cnum, data| {
393- if data. name ( ) == name && meta_hash == data. hash ( ) {
394- assert ! ( hash. is_none( ) ) ;
395- result = LookupResult :: Previous ( cnum) ;
396- }
397- } ) ;
398- result
384+ match self . load ( & mut load_ctxt) {
385+ Some ( result) => result,
386+ None => load_ctxt. report_load_errs ( ) ,
387+ }
399388 }
400389 } ;
401390
402391 match result {
403- LookupResult :: Previous ( cnum) => {
392+ LoadResult :: Previous ( cnum) => {
404393 let data = self . cstore . get_crate_data ( cnum) ;
405394 if explicitly_linked && !data. explicitly_linked . get ( ) {
406395 data. explicitly_linked . set ( explicitly_linked) ;
407396 }
408397 ( cnum, data, self . cstore . used_crate_source ( cnum) )
409398 }
410- LookupResult :: Loaded ( library) => {
399+ LoadResult :: Loaded ( library) => {
411400 self . register_crate ( root, ident, name, span, library,
412401 explicitly_linked)
413402 }
414403 }
415404 }
416405
406+ fn load ( & mut self , loader : & mut loader:: Context ) -> Option < LoadResult > {
407+ let library = match loader. maybe_load_library_crate ( ) {
408+ Some ( lib) => lib,
409+ None => return None ,
410+ } ;
411+
412+ // In the case that we're loading a crate, but not matching
413+ // against a hash, we could load a crate which has the same hash
414+ // as an already loaded crate. If this is the case prevent
415+ // duplicates by just using the first crate.
416+ //
417+ // Note that we only do this for target triple crates, though, as we
418+ // don't want to match a host crate against an equivalent target one
419+ // already loaded.
420+ if loader. triple == self . sess . opts . target_triple {
421+ let meta_hash = decoder:: get_crate_hash ( library. metadata . as_slice ( ) ) ;
422+ let meta_name = decoder:: get_crate_name ( library. metadata . as_slice ( ) )
423+ . to_string ( ) ;
424+ let mut result = LoadResult :: Loaded ( library) ;
425+ self . cstore . iter_crate_data ( |cnum, data| {
426+ if data. name ( ) == meta_name && meta_hash == data. hash ( ) {
427+ assert ! ( loader. hash. is_none( ) ) ;
428+ result = LoadResult :: Previous ( cnum) ;
429+ }
430+ } ) ;
431+ Some ( result)
432+ } else {
433+ Some ( LoadResult :: Loaded ( library) )
434+ }
435+ }
436+
417437 fn update_extern_crate ( & mut self ,
418438 cnum : ast:: CrateNum ,
419439 mut extern_crate : ExternCrate )
@@ -488,35 +508,46 @@ impl<'a> CrateReader<'a> {
488508 rejected_via_kind : vec ! ( ) ,
489509 should_match_name : true ,
490510 } ;
491- let library = match load_ctxt. maybe_load_library_crate ( ) {
492- Some ( l) => l,
493- None if is_cross => {
494- // Try loading from target crates. This will abort later if we
495- // try to load a plugin registrar function,
496- target_only = true ;
497- should_link = info. should_link ;
498-
499- load_ctxt. target = & self . sess . target . target ;
500- load_ctxt. triple = target_triple;
501- load_ctxt. filesearch = self . sess . target_filesearch ( PathKind :: Crate ) ;
502- load_ctxt. load_library_crate ( )
511+ let library = self . load ( & mut load_ctxt) . or_else ( || {
512+ if !is_cross {
513+ return None
503514 }
504- None => { load_ctxt. report_load_errs ( ) ; } ,
515+ // Try loading from target crates. This will abort later if we
516+ // try to load a plugin registrar function,
517+ target_only = true ;
518+ should_link = info. should_link ;
519+
520+ load_ctxt. target = & self . sess . target . target ;
521+ load_ctxt. triple = target_triple;
522+ load_ctxt. filesearch = self . sess . target_filesearch ( PathKind :: Crate ) ;
523+
524+ self . load ( & mut load_ctxt)
525+ } ) ;
526+ let library = match library {
527+ Some ( l) => l,
528+ None => load_ctxt. report_load_errs ( ) ,
505529 } ;
506530
507- let dylib = library. dylib . clone ( ) ;
508- let register = should_link && self . existing_match ( & info. name ,
509- None ,
510- PathKind :: Crate ) . is_none ( ) ;
511- let metadata = if register {
512- // Register crate now to avoid double-reading metadata
513- let ( _, cmd, _) = self . register_crate ( & None , & info. ident ,
514- & info. name , span, library,
515- true ) ;
516- PMDSource :: Registered ( cmd)
517- } else {
518- // Not registering the crate; just hold on to the metadata
519- PMDSource :: Owned ( library. metadata )
531+ let ( dylib, metadata) = match library {
532+ LoadResult :: Previous ( cnum) => {
533+ let dylib = self . cstore . opt_used_crate_source ( cnum) . unwrap ( ) . dylib ;
534+ let data = self . cstore . get_crate_data ( cnum) ;
535+ ( dylib, PMDSource :: Registered ( data) )
536+ }
537+ LoadResult :: Loaded ( library) => {
538+ let dylib = library. dylib . clone ( ) ;
539+ let metadata = if should_link {
540+ // Register crate now to avoid double-reading metadata
541+ let ( _, cmd, _) = self . register_crate ( & None , & info. ident ,
542+ & info. name , span,
543+ library, true ) ;
544+ PMDSource :: Registered ( cmd)
545+ } else {
546+ // Not registering the crate; just hold on to the metadata
547+ PMDSource :: Owned ( library. metadata )
548+ } ;
549+ ( dylib, metadata)
550+ }
520551 } ;
521552
522553 ExtensionCrate {
0 commit comments