@@ -143,6 +143,11 @@ impl PMDSource {
143
143
}
144
144
}
145
145
146
+ enum LoadResult {
147
+ Previous ( ast:: CrateNum ) ,
148
+ Loaded ( loader:: Library ) ,
149
+ }
150
+
146
151
impl < ' a > CrateReader < ' a > {
147
152
pub fn new ( sess : & ' a Session ,
148
153
cstore : & ' a CStore ,
@@ -358,12 +363,8 @@ impl<'a> CrateReader<'a> {
358
363
kind : PathKind ,
359
364
explicitly_linked : bool )
360
365
-> ( ast:: CrateNum , Rc < cstore:: crate_metadata > , cstore:: CrateSource ) {
361
- enum LookupResult {
362
- Previous ( ast:: CrateNum ) ,
363
- Loaded ( loader:: Library ) ,
364
- }
365
366
let result = match self . existing_match ( name, hash, kind) {
366
- Some ( cnum) => LookupResult :: Previous ( cnum) ,
367
+ Some ( cnum) => LoadResult :: Previous ( cnum) ,
367
368
None => {
368
369
let mut load_ctxt = loader:: Context {
369
370
sess : self . sess ,
@@ -380,40 +381,59 @@ impl<'a> CrateReader<'a> {
380
381
rejected_via_kind : vec ! ( ) ,
381
382
should_match_name : true ,
382
383
} ;
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
+ }
399
388
}
400
389
} ;
401
390
402
391
match result {
403
- LookupResult :: Previous ( cnum) => {
392
+ LoadResult :: Previous ( cnum) => {
404
393
let data = self . cstore . get_crate_data ( cnum) ;
405
394
if explicitly_linked && !data. explicitly_linked . get ( ) {
406
395
data. explicitly_linked . set ( explicitly_linked) ;
407
396
}
408
397
( cnum, data, self . cstore . used_crate_source ( cnum) )
409
398
}
410
- LookupResult :: Loaded ( library) => {
399
+ LoadResult :: Loaded ( library) => {
411
400
self . register_crate ( root, ident, name, span, library,
412
401
explicitly_linked)
413
402
}
414
403
}
415
404
}
416
405
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
+
417
437
fn update_extern_crate ( & mut self ,
418
438
cnum : ast:: CrateNum ,
419
439
mut extern_crate : ExternCrate )
@@ -488,35 +508,46 @@ impl<'a> CrateReader<'a> {
488
508
rejected_via_kind : vec ! ( ) ,
489
509
should_match_name : true ,
490
510
} ;
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
503
514
}
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 ( ) ,
505
529
} ;
506
530
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
+ }
520
551
} ;
521
552
522
553
ExtensionCrate {
0 commit comments