@@ -470,20 +470,17 @@ impl<'a> Context<'a> {
470
470
// A Library candidate is created if the metadata for the set of
471
471
// libraries corresponds to the crate id and hash criteria that this
472
472
// search is being performed for.
473
- let mut libraries = Vec :: new ( ) ;
473
+ let mut libraries = HashMap :: new ( ) ;
474
474
for ( _hash, ( rlibs, dylibs) ) in candidates {
475
- let mut metadata = None ;
476
- let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut metadata) ;
477
- let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut metadata) ;
478
- match metadata {
479
- Some ( metadata) => {
480
- libraries. push ( Library {
481
- dylib : dylib,
482
- rlib : rlib,
483
- metadata : metadata,
484
- } )
485
- }
486
- None => { }
475
+ let mut slot = None ;
476
+ let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut slot) ;
477
+ let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut slot) ;
478
+ if let Some ( ( h, m) ) = slot {
479
+ libraries. insert ( h, Library {
480
+ dylib : dylib,
481
+ rlib : rlib,
482
+ metadata : m,
483
+ } ) ;
487
484
}
488
485
}
489
486
@@ -492,13 +489,13 @@ impl<'a> Context<'a> {
492
489
// libraries or not.
493
490
match libraries. len ( ) {
494
491
0 => None ,
495
- 1 => Some ( libraries. into_iter ( ) . next ( ) . unwrap ( ) ) ,
492
+ 1 => Some ( libraries. into_iter ( ) . next ( ) . unwrap ( ) . 1 ) ,
496
493
_ => {
497
494
let mut err = struct_span_err ! ( self . sess, self . span, E0464 ,
498
495
"multiple matching crates for `{}`" ,
499
496
self . crate_name) ;
500
497
err. note ( "candidates:" ) ;
501
- for lib in & libraries {
498
+ for ( _ , lib) in libraries {
502
499
match lib. dylib {
503
500
Some ( ( ref p, _) ) => {
504
501
err. note ( & format ! ( "path: {}" ,
@@ -532,13 +529,13 @@ impl<'a> Context<'a> {
532
529
// be read, it is assumed that the file isn't a valid rust library (no
533
530
// errors are emitted).
534
531
fn extract_one ( & mut self , m : HashMap < PathBuf , PathKind > , flavor : CrateFlavor ,
535
- slot : & mut Option < MetadataBlob > ) -> Option < ( PathBuf , PathKind ) > {
536
- let mut ret = None :: < ( PathBuf , PathKind ) > ;
532
+ slot : & mut Option < ( Svh , MetadataBlob ) > ) -> Option < ( PathBuf , PathKind ) > {
533
+ let mut ret: Option < ( PathBuf , PathKind ) > = None ;
537
534
let mut error = 0 ;
538
535
539
536
if slot. is_some ( ) {
540
537
// FIXME(#10786): for an optimization, we only read one of the
541
- // library's metadata sections. In theory we should
538
+ // libraries' metadata sections. In theory we should
542
539
// read both, but reading dylib metadata is quite
543
540
// slow.
544
541
if m. is_empty ( ) {
@@ -551,10 +548,10 @@ impl<'a> Context<'a> {
551
548
let mut err: Option < DiagnosticBuilder > = None ;
552
549
for ( lib, kind) in m {
553
550
info ! ( "{} reading metadata from: {}" , flavor, lib. display( ) ) ;
554
- let metadata = match get_metadata_section ( self . target , flavor, & lib) {
551
+ let ( hash , metadata) = match get_metadata_section ( self . target , flavor, & lib) {
555
552
Ok ( blob) => {
556
- if self . crate_matches ( blob. as_slice ( ) , & lib) {
557
- blob
553
+ if let Some ( h ) = self . crate_matches ( blob. as_slice ( ) , & lib) {
554
+ ( h , blob)
558
555
} else {
559
556
info ! ( "metadata mismatch" ) ;
560
557
continue
@@ -565,12 +562,8 @@ impl<'a> Context<'a> {
565
562
continue
566
563
}
567
564
} ;
568
- // If we've already found a candidate and we're not matching hashes,
569
- // emit an error about duplicate candidates found. If we're matching
570
- // based on a hash, however, then if we've gotten this far both
571
- // candidates have the same hash, so they're not actually
572
- // duplicates that we should warn about.
573
- if ret. is_some ( ) && self . hash . is_none ( ) {
565
+ // If we see multiple hashes, emit an error about duplicate candidates.
566
+ if slot. as_ref ( ) . map_or ( false , |s| s. 0 != hash) {
574
567
let mut e = struct_span_err ! ( self . sess, self . span, E0465 ,
575
568
"multiple {} candidates for `{}` found" ,
576
569
flavor, self . crate_name) ;
@@ -583,7 +576,7 @@ impl<'a> Context<'a> {
583
576
}
584
577
err = Some ( e) ;
585
578
error = 1 ;
586
- ret = None ;
579
+ * slot = None ;
587
580
}
588
581
if error > 0 {
589
582
error += 1 ;
@@ -592,7 +585,7 @@ impl<'a> Context<'a> {
592
585
lib. display( ) ) ) ;
593
586
continue
594
587
}
595
- * slot = Some ( metadata) ;
588
+ * slot = Some ( ( hash , metadata) ) ;
596
589
ret = Some ( ( lib, kind) ) ;
597
590
}
598
591
@@ -604,22 +597,20 @@ impl<'a> Context<'a> {
604
597
}
605
598
}
606
599
607
- fn crate_matches ( & mut self , crate_data : & [ u8 ] , libpath : & Path ) -> bool {
600
+ fn crate_matches ( & mut self , crate_data : & [ u8 ] , libpath : & Path ) -> Option < Svh > {
608
601
if self . should_match_name {
609
602
match decoder:: maybe_get_crate_name ( crate_data) {
610
603
Some ( ref name) if self . crate_name == * name => { }
611
- _ => { info ! ( "Rejecting via crate name" ) ; return false }
604
+ _ => { info ! ( "Rejecting via crate name" ) ; return None }
612
605
}
613
606
}
614
607
let hash = match decoder:: maybe_get_crate_hash ( crate_data) {
615
- Some ( hash) => hash, None => {
616
- info ! ( "Rejecting via lack of crate hash" ) ;
617
- return false ;
618
- }
608
+ None => { info ! ( "Rejecting via lack of crate hash" ) ; return None ; }
609
+ Some ( h) => h,
619
610
} ;
620
611
621
612
let triple = match decoder:: get_crate_triple ( crate_data) {
622
- None => { debug ! ( "triple not present" ) ; return false }
613
+ None => { debug ! ( "triple not present" ) ; return None }
623
614
Some ( t) => t,
624
615
} ;
625
616
if triple != self . triple {
@@ -628,24 +619,21 @@ impl<'a> Context<'a> {
628
619
path : libpath. to_path_buf ( ) ,
629
620
got : triple. to_string ( )
630
621
} ) ;
631
- return false ;
622
+ return None ;
632
623
}
633
624
634
- match self . hash {
635
- None => true ,
636
- Some ( myhash) => {
637
- if * myhash != hash {
638
- info ! ( "Rejecting via hash: expected {} got {}" , * myhash, hash) ;
639
- self . rejected_via_hash . push ( CrateMismatch {
640
- path : libpath. to_path_buf ( ) ,
641
- got : myhash. as_str ( ) . to_string ( )
642
- } ) ;
643
- false
644
- } else {
645
- true
646
- }
625
+ if let Some ( myhash) = self . hash {
626
+ if * myhash != hash {
627
+ info ! ( "Rejecting via hash: expected {} got {}" , * myhash, hash) ;
628
+ self . rejected_via_hash . push ( CrateMismatch {
629
+ path : libpath. to_path_buf ( ) ,
630
+ got : myhash. as_str ( ) . to_string ( )
631
+ } ) ;
632
+ return None ;
647
633
}
648
634
}
635
+
636
+ Some ( hash)
649
637
}
650
638
651
639
@@ -717,13 +705,13 @@ impl<'a> Context<'a> {
717
705
} ;
718
706
719
707
// Extract the rlib/dylib pair.
720
- let mut metadata = None ;
721
- let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut metadata ) ;
722
- let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut metadata ) ;
708
+ let mut slot = None ;
709
+ let rlib = self . extract_one ( rlibs, CrateFlavor :: Rlib , & mut slot ) ;
710
+ let dylib = self . extract_one ( dylibs, CrateFlavor :: Dylib , & mut slot ) ;
723
711
724
712
if rlib. is_none ( ) && dylib. is_none ( ) { return None }
725
- match metadata {
726
- Some ( metadata) => Some ( Library {
713
+ match slot {
714
+ Some ( ( _ , metadata) ) => Some ( Library {
727
715
dylib : dylib,
728
716
rlib : rlib,
729
717
metadata : metadata,
0 commit comments