@@ -223,7 +223,7 @@ use rustc_data_structures::sync::MetadataRef;
223223use  rustc_errors:: { struct_span_err,  FatalError } ; 
224224use  rustc_session:: config:: { self ,  CrateType } ; 
225225use  rustc_session:: cstore:: { CrateSource ,  MetadataLoader } ; 
226- use  rustc_session:: filesearch:: { FileDoesntMatch ,   FileMatches ,   FileSearch } ; 
226+ use  rustc_session:: filesearch:: FileSearch ; 
227227use  rustc_session:: search_paths:: PathKind ; 
228228use  rustc_session:: utils:: CanonicalizedPath ; 
229229use  rustc_session:: Session ; 
@@ -371,15 +371,20 @@ impl<'a> CrateLocator<'a> {
371371        extra_prefix :  & str , 
372372        seen_paths :  & mut  FxHashSet < PathBuf > , 
373373    )  -> Result < Option < Library > ,  CrateError >  { 
374-         // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" 
375-         let  dylib_prefix = format ! ( "{}{}{}" ,  self . target. dll_prefix,  self . crate_name,  extra_prefix) ; 
376-         let  rlib_prefix = format ! ( "lib{}{}" ,  self . crate_name,  extra_prefix) ; 
374+         let  rmeta_prefix = & format ! ( "lib{}{}" ,  self . crate_name,  extra_prefix) ; 
375+         let  rlib_prefix = rmeta_prefix; 
376+         let  dylib_prefix =
377+             & format ! ( "{}{}{}" ,  self . target. dll_prefix,  self . crate_name,  extra_prefix) ; 
377378        let  staticlib_prefix =
378-             format ! ( "{}{}{}" ,  self . target. staticlib_prefix,  self . crate_name,  extra_prefix) ; 
379+             & format ! ( "{}{}{}" ,  self . target. staticlib_prefix,  self . crate_name,  extra_prefix) ; 
380+ 
381+         let  rmeta_suffix = ".rmeta" ; 
382+         let  rlib_suffix = ".rlib" ; 
383+         let  dylib_suffix = & self . target . dll_suffix ; 
384+         let  staticlib_suffix = & self . target . staticlib_suffix ; 
379385
380386        let  mut  candidates:  FxHashMap < _ ,  ( FxHashMap < _ ,  _ > ,  FxHashMap < _ ,  _ > ,  FxHashMap < _ ,  _ > ) >  =
381387            Default :: default ( ) ; 
382-         let  mut  staticlibs = vec ! [ ] ; 
383388
384389        // First, find all possible candidate rlibs and dylibs purely based on 
385390        // the name of the files themselves. We're trying to match against an 
@@ -394,46 +399,50 @@ impl<'a> CrateLocator<'a> {
394399        // of the crate id (path/name/id). 
395400        // 
396401        // The goal of this step is to look at as little metadata as possible. 
397-         self . filesearch . search ( |spf,  kind| { 
398-             let  file = match  & spf. file_name_str  { 
399-                 None  => return  FileDoesntMatch , 
400-                 Some ( file)  => file, 
401-             } ; 
402-             let  ( hash,  found_kind)  = if  file. starts_with ( & rlib_prefix)  && file. ends_with ( ".rlib" )  { 
403-                 ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( )  - ".rlib" . len ( ) ) ] ,  CrateFlavor :: Rlib ) 
404-             }  else  if  file. starts_with ( & rlib_prefix)  && file. ends_with ( ".rmeta" )  { 
405-                 ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( )  - ".rmeta" . len ( ) ) ] ,  CrateFlavor :: Rmeta ) 
406-             }  else  if  file. starts_with ( & dylib_prefix)  && file. ends_with ( & self . target . dll_suffix )  { 
407-                 ( 
408-                     & file[ ( dylib_prefix. len ( ) ) ..( file. len ( )  - self . target . dll_suffix . len ( ) ) ] , 
409-                     CrateFlavor :: Dylib , 
410-                 ) 
411-             }  else  { 
412-                 if  file. starts_with ( & staticlib_prefix) 
413-                     && file. ends_with ( & self . target . staticlib_suffix ) 
414-                 { 
415-                     staticlibs
416-                         . push ( CrateMismatch  {  path :  spf. path . clone ( ) ,  got :  "static" . to_string ( )  } ) ; 
417-                 } 
418-                 return  FileDoesntMatch ; 
419-             } ; 
402+         // Unfortunately, the prefix-based matching sometimes is over-eager. 
403+         // E.g. if `rlib_suffix` is `libstd` it'll match the file 
404+         // `libstd_detect-8d6701fb958915ad.rlib` (incorrect) as well as 
405+         // `libstd-f3ab5b1dea981f17.rlib` (correct). But this is hard to avoid 
406+         // given that `extra_filename` comes from the `-C extra-filename` 
407+         // option and thus can be anything, and the incorrect match will be 
408+         // handled safely in `extract_one`. 
409+         for  search_path in  self . filesearch . search_paths ( )  { 
410+             debug ! ( "searching {}" ,  search_path. dir. display( ) ) ; 
411+             for  spf in  search_path. files . iter ( )  { 
412+                 debug ! ( "testing {}" ,  spf. path. display( ) ) ; 
413+ 
414+                 let  f = & spf. file_name_str ; 
415+                 let  ( hash,  kind)  = if  f. starts_with ( rlib_prefix)  && f. ends_with ( rlib_suffix)  { 
416+                     ( & f[ rlib_prefix. len ( ) ..( f. len ( )  - rlib_suffix. len ( ) ) ] ,  CrateFlavor :: Rlib ) 
417+                 }  else  if  f. starts_with ( rmeta_prefix)  && f. ends_with ( rmeta_suffix)  { 
418+                     ( & f[ rmeta_prefix. len ( ) ..( f. len ( )  - rmeta_suffix. len ( ) ) ] ,  CrateFlavor :: Rmeta ) 
419+                 }  else  if  f. starts_with ( dylib_prefix)  && f. ends_with ( dylib_suffix)  { 
420+                     ( & f[ dylib_prefix. len ( ) ..( f. len ( )  - dylib_suffix. len ( ) ) ] ,  CrateFlavor :: Dylib ) 
421+                 }  else  { 
422+                     if  f. starts_with ( staticlib_prefix)  && f. ends_with ( staticlib_suffix)  { 
423+                         self . crate_rejections . via_kind . push ( CrateMismatch  { 
424+                             path :  spf. path . clone ( ) , 
425+                             got :  "static" . to_string ( ) , 
426+                         } ) ; 
427+                     } 
428+                     continue ; 
429+                 } ; 
420430
421-             info ! ( "lib candidate: {}" ,  spf. path. display( ) ) ; 
431+                  info ! ( "lib candidate: {}" ,  spf. path. display( ) ) ; 
422432
423-             let  ( rlibs,  rmetas,  dylibs)  = candidates. entry ( hash. to_string ( ) ) . or_default ( ) ; 
424-             let  path = fs:: canonicalize ( & spf. path ) . unwrap_or_else ( |_| spf. path . clone ( ) ) ; 
425-             if  seen_paths. contains ( & path)  { 
426-                 return  FileDoesntMatch ; 
427-             } ; 
428-             seen_paths. insert ( path. clone ( ) ) ; 
429-             match  found_kind { 
430-                 CrateFlavor :: Rlib  => rlibs. insert ( path,  kind) , 
431-                 CrateFlavor :: Rmeta  => rmetas. insert ( path,  kind) , 
432-                 CrateFlavor :: Dylib  => dylibs. insert ( path,  kind) , 
433-             } ; 
434-             FileMatches 
435-         } ) ; 
436-         self . crate_rejections . via_kind . extend ( staticlibs) ; 
433+                 let  ( rlibs,  rmetas,  dylibs)  = candidates. entry ( hash. to_string ( ) ) . or_default ( ) ; 
434+                 let  path = fs:: canonicalize ( & spf. path ) . unwrap_or_else ( |_| spf. path . clone ( ) ) ; 
435+                 if  seen_paths. contains ( & path)  { 
436+                     continue ; 
437+                 } ; 
438+                 seen_paths. insert ( path. clone ( ) ) ; 
439+                 match  kind { 
440+                     CrateFlavor :: Rlib  => rlibs. insert ( path,  search_path. kind ) , 
441+                     CrateFlavor :: Rmeta  => rmetas. insert ( path,  search_path. kind ) , 
442+                     CrateFlavor :: Dylib  => dylibs. insert ( path,  search_path. kind ) , 
443+                 } ; 
444+             } 
445+         } 
437446
438447        // We have now collected all known libraries into a set of candidates 
439448        // keyed of the filename hash listed. For each filename, we also have a 
0 commit comments