@@ -471,8 +471,8 @@ pub enum LinkError {
471471 #[ error( "Failed to allocate function table indices: {0}" ) ]
472472 TableAllocationError ( RuntimeError ) ,
473473
474- #[ error( "File system error: {0 }" ) ]
475- FileSystemError ( # [ from ] FsError ) ,
474+ #[ error( "Failed to find shared library {0}: {1 }" ) ]
475+ SharedLibraryMissing ( String , FsErrors ) ,
476476
477477 #[ error( "Module is not a dynamic library" ) ]
478478 NotDynamicLibrary ,
@@ -519,6 +519,25 @@ pub enum LinkError {
519519 MissingTlsInitializer ,
520520}
521521
522+ #[ derive( Debug ) ]
523+ pub enum FsErrors {
524+ SingleError ( FsError ) ,
525+ MultipleErrors ( Vec < ( PathBuf , FsError ) > ) ,
526+ }
527+ impl std:: fmt:: Display for FsErrors {
528+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
529+ match self {
530+ FsErrors :: SingleError ( e) => std:: fmt:: Display :: fmt ( & e, f) ,
531+ FsErrors :: MultipleErrors ( errors) => {
532+ for ( path, error) in errors {
533+ write ! ( f, "\n {}: {}" , path. display( ) , error) ?;
534+ }
535+ Ok ( ( ) )
536+ }
537+ }
538+ }
539+ }
540+
522541#[ derive( Debug ) ]
523542enum PartiallyResolvedExport {
524543 Function ( Function ) ,
@@ -3566,14 +3585,25 @@ async fn locate_module(
35663585
35673586 if module_path. is_absolute ( ) {
35683587 trace ! ( ?module_path, "Locating module with absolute path" ) ;
3569- Ok ( try_load ( & fs. root_fs , module_path) . await ?)
3588+ try_load ( & fs. root_fs , module_path) . await . map_err ( |e| {
3589+ LinkError :: SharedLibraryMissing (
3590+ module_path. to_string_lossy ( ) . into_owned ( ) ,
3591+ FsErrors :: SingleError ( e) ,
3592+ )
3593+ } )
35703594 } else if module_path. components ( ) . count ( ) > 1 {
35713595 trace ! ( ?module_path, "Locating module with relative path" ) ;
3572- Ok ( try_load (
3596+ try_load (
35733597 & fs. root_fs ,
35743598 fs. relative_path_to_absolute ( module_path. to_string_lossy ( ) . into_owned ( ) ) ,
35753599 )
3576- . await ?)
3600+ . await
3601+ . map_err ( |e| {
3602+ LinkError :: SharedLibraryMissing (
3603+ module_path. to_string_lossy ( ) . into_owned ( ) ,
3604+ FsErrors :: SingleError ( e) ,
3605+ )
3606+ } )
35773607 } else {
35783608 // Go through all dynamic library lookup paths
35793609 // Note: a path without a slash does *not* look at the current directory. This is by design.
@@ -3585,25 +3615,30 @@ async fn locate_module(
35853615 ?module_path,
35863616 "Locating module by name in default runtime path"
35873617 ) ;
3588-
3589- if let Some ( library_path) = library_path {
3590- for path in library_path {
3591- if let Ok ( ret) = try_load ( & fs. root_fs , path. as_ref ( ) . join ( module_path) ) . await {
3618+ let search_paths = library_path
3619+ . iter ( )
3620+ . flat_map ( |paths| paths. iter ( ) . map ( AsRef :: as_ref) )
3621+ // Add default runtime paths
3622+ . chain ( DEFAULT_RUNTIME_PATH . iter ( ) . map ( |path| Path :: new ( path) ) ) ;
3623+
3624+ let mut errors: Vec < ( PathBuf , FsError ) > = Vec :: new ( ) ;
3625+ for path in search_paths {
3626+ let full_path = path. join ( module_path) ;
3627+ trace ! ( ?module_path, full_path = ?full_path, "Searching module" ) ;
3628+ match try_load ( & fs. root_fs , & full_path) . await {
3629+ Ok ( ret) => {
35923630 trace ! ( ?module_path, full_path = ?ret. 0 , "Located module" ) ;
35933631 return Ok ( ret) ;
35943632 }
3595- }
3596- }
3597-
3598- for path in DEFAULT_RUNTIME_PATH {
3599- if let Ok ( ret) = try_load ( & fs. root_fs , Path :: new ( path) . join ( module_path) ) . await {
3600- trace ! ( ?module_path, full_path = ?ret. 0 , "Located module" ) ;
3601- return Ok ( ret) ;
3602- }
3633+ Err ( e) => errors. push ( ( full_path, e) ) ,
3634+ } ;
36033635 }
36043636
36053637 trace ! ( ?module_path, "Failed to locate module" ) ;
3606- Err ( FsError :: EntryNotFound . into ( ) )
3638+ Err ( LinkError :: SharedLibraryMissing (
3639+ module_path. to_string_lossy ( ) . into_owned ( ) ,
3640+ FsErrors :: MultipleErrors ( errors) ,
3641+ ) )
36073642 }
36083643}
36093644
0 commit comments