@@ -470,20 +470,17 @@ impl<'a> Context<'a> {
470470 // A Library candidate is created if the metadata for the set of
471471 // libraries corresponds to the crate id and hash criteria that this
472472 // search is being performed for.
473- let mut libraries = Vec :: new ( ) ;
473+ let mut libraries = HashMap :: new ( ) ;
474474 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+ } ) ;
487484 }
488485 }
489486
@@ -492,13 +489,13 @@ impl<'a> Context<'a> {
492489 // libraries or not.
493490 match libraries. len ( ) {
494491 0 => None ,
495- 1 => Some ( libraries. into_iter ( ) . next ( ) . unwrap ( ) ) ,
492+ 1 => Some ( libraries. into_iter ( ) . next ( ) . unwrap ( ) . 1 ) ,
496493 _ => {
497494 let mut err = struct_span_err ! ( self . sess, self . span, E0464 ,
498495 "multiple matching crates for `{}`" ,
499496 self . crate_name) ;
500497 err. note ( "candidates:" ) ;
501- for lib in & libraries {
498+ for ( _ , lib) in libraries {
502499 match lib. dylib {
503500 Some ( ( ref p, _) ) => {
504501 err. note ( & format ! ( "path: {}" ,
@@ -532,13 +529,13 @@ impl<'a> Context<'a> {
532529 // be read, it is assumed that the file isn't a valid rust library (no
533530 // errors are emitted).
534531 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 ;
537534 let mut error = 0 ;
538535
539536 if slot. is_some ( ) {
540537 // 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
542539 // read both, but reading dylib metadata is quite
543540 // slow.
544541 if m. is_empty ( ) {
@@ -551,10 +548,10 @@ impl<'a> Context<'a> {
551548 let mut err: Option < DiagnosticBuilder > = None ;
552549 for ( lib, kind) in m {
553550 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) {
555552 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)
558555 } else {
559556 info ! ( "metadata mismatch" ) ;
560557 continue
@@ -565,12 +562,8 @@ impl<'a> Context<'a> {
565562 continue
566563 }
567564 } ;
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) {
574567 let mut e = struct_span_err ! ( self . sess, self . span, E0465 ,
575568 "multiple {} candidates for `{}` found" ,
576569 flavor, self . crate_name) ;
@@ -583,7 +576,7 @@ impl<'a> Context<'a> {
583576 }
584577 err = Some ( e) ;
585578 error = 1 ;
586- ret = None ;
579+ * slot = None ;
587580 }
588581 if error > 0 {
589582 error += 1 ;
@@ -592,7 +585,7 @@ impl<'a> Context<'a> {
592585 lib. display( ) ) ) ;
593586 continue
594587 }
595- * slot = Some ( metadata) ;
588+ * slot = Some ( ( hash , metadata) ) ;
596589 ret = Some ( ( lib, kind) ) ;
597590 }
598591
@@ -604,22 +597,20 @@ impl<'a> Context<'a> {
604597 }
605598 }
606599
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 > {
608601 if self . should_match_name {
609602 match decoder:: maybe_get_crate_name ( crate_data) {
610603 Some ( ref name) if self . crate_name == * name => { }
611- _ => { info ! ( "Rejecting via crate name" ) ; return false }
604+ _ => { info ! ( "Rejecting via crate name" ) ; return None }
612605 }
613606 }
614607 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,
619610 } ;
620611
621612 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 }
623614 Some ( t) => t,
624615 } ;
625616 if triple != self . triple {
@@ -628,24 +619,21 @@ impl<'a> Context<'a> {
628619 path : libpath. to_path_buf ( ) ,
629620 got : triple. to_string ( )
630621 } ) ;
631- return false ;
622+ return None ;
632623 }
633624
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 ;
647633 }
648634 }
635+
636+ Some ( hash)
649637 }
650638
651639
@@ -717,13 +705,13 @@ impl<'a> Context<'a> {
717705 } ;
718706
719707 // 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 ) ;
723711
724712 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 {
727715 dylib : dylib,
728716 rlib : rlib,
729717 metadata : metadata,
0 commit comments