@@ -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