@@ -5,15 +5,15 @@ mod json_project;
55mod sysroot;
66
77use std:: {
8- error :: Error ,
8+ fmt ,
99 fs:: File ,
1010 io:: BufReader ,
1111 path:: { Path , PathBuf } ,
1212 process:: Command ,
1313} ;
1414
1515use ra_cfg:: CfgOptions ;
16- use ra_db:: { CrateGraph , CrateId , Edition , Env , FileId } ;
16+ use ra_db:: { CrateGraph , CrateId , Edition , Env , FileId , ParseEditionError } ;
1717use rustc_hash:: FxHashMap ;
1818use serde_json:: from_reader;
1919
@@ -23,8 +23,57 @@ pub use crate::{
2323 sysroot:: Sysroot ,
2424} ;
2525
26- // FIXME use proper error enum
27- pub type Result < T > = :: std:: result:: Result < T , Box < dyn Error + Send + Sync > > ;
26+ #[ derive( Debug ) ]
27+ pub enum WorkspaceError {
28+ CargoMetadataFailed ( cargo_metadata:: Error ) ,
29+ CargoTomlNotFound ( PathBuf ) ,
30+ NoStdLib ( PathBuf ) ,
31+ OpenWorkspaceError ( std:: io:: Error ) ,
32+ ParseEditionError ( ParseEditionError ) ,
33+ ReadWorkspaceError ( serde_json:: Error ) ,
34+ RustcCfgError ,
35+ RustcError ( std:: io:: Error ) ,
36+ RustcOutputError ( std:: string:: FromUtf8Error ) ,
37+ SysrootNotFound ,
38+ }
39+
40+ impl fmt:: Display for WorkspaceError {
41+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
42+ match self {
43+ Self :: OpenWorkspaceError ( err) | Self :: RustcError ( err) => write ! ( f, "{}" , err) ,
44+ Self :: ParseEditionError ( err) => write ! ( f, "{}" , err) ,
45+ Self :: ReadWorkspaceError ( err) => write ! ( f, "{}" , err) ,
46+ Self :: RustcOutputError ( err) => write ! ( f, "{}" , err) ,
47+ Self :: CargoMetadataFailed ( err) => write ! ( f, "cargo metadata failed: {}" , err) ,
48+ Self :: RustcCfgError => write ! ( f, "failed to get rustc cfgs" ) ,
49+ Self :: SysrootNotFound => write ! ( f, "failed to locate sysroot" ) ,
50+ Self :: CargoTomlNotFound ( path) => {
51+ write ! ( f, "can't find Cargo.toml at {}" , path. display( ) )
52+ }
53+ Self :: NoStdLib ( sysroot) => write ! (
54+ f,
55+ "can't load standard library from sysroot\n \
56+ {:?}\n \
57+ try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
58+ sysroot,
59+ ) ,
60+ }
61+ }
62+ }
63+
64+ impl std:: error:: Error for WorkspaceError { }
65+
66+ impl From < ParseEditionError > for WorkspaceError {
67+ fn from ( err : ParseEditionError ) -> Self {
68+ Self :: ParseEditionError ( err. into ( ) )
69+ }
70+ }
71+
72+ impl From < cargo_metadata:: Error > for WorkspaceError {
73+ fn from ( err : cargo_metadata:: Error ) -> Self {
74+ Self :: CargoMetadataFailed ( err. into ( ) )
75+ }
76+ }
2877
2978#[ derive( Debug , Clone ) ]
3079pub enum ProjectWorkspace {
@@ -60,20 +109,27 @@ impl PackageRoot {
60109}
61110
62111impl ProjectWorkspace {
63- pub fn discover ( path : & Path , cargo_features : & CargoFeatures ) -> Result < ProjectWorkspace > {
112+ pub fn discover (
113+ path : & Path ,
114+ cargo_features : & CargoFeatures ,
115+ ) -> Result < ProjectWorkspace , WorkspaceError > {
64116 ProjectWorkspace :: discover_with_sysroot ( path, true , cargo_features)
65117 }
66118
67119 pub fn discover_with_sysroot (
68120 path : & Path ,
69121 with_sysroot : bool ,
70122 cargo_features : & CargoFeatures ,
71- ) -> Result < ProjectWorkspace > {
123+ ) -> Result < ProjectWorkspace , WorkspaceError > {
72124 match find_rust_project_json ( path) {
73125 Some ( json_path) => {
74- let file = File :: open ( json_path) ?;
126+ let file =
127+ File :: open ( json_path) . map_err ( |err| WorkspaceError :: OpenWorkspaceError ( err) ) ?;
75128 let reader = BufReader :: new ( file) ;
76- Ok ( ProjectWorkspace :: Json { project : from_reader ( reader) ? } )
129+ Ok ( ProjectWorkspace :: Json {
130+ project : from_reader ( reader)
131+ . map_err ( |err| WorkspaceError :: ReadWorkspaceError ( err) ) ?,
132+ } )
77133 }
78134 None => {
79135 let cargo_toml = find_cargo_toml ( path) ?;
@@ -350,7 +406,7 @@ fn find_rust_project_json(path: &Path) -> Option<PathBuf> {
350406 None
351407}
352408
353- fn find_cargo_toml ( path : & Path ) -> Result < PathBuf > {
409+ fn find_cargo_toml ( path : & Path ) -> Result < PathBuf , WorkspaceError > {
354410 if path. ends_with ( "Cargo.toml" ) {
355411 return Ok ( path. to_path_buf ( ) ) ;
356412 }
@@ -362,7 +418,7 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
362418 }
363419 curr = path. parent ( ) ;
364420 }
365- Err ( format ! ( "can't find Cargo.toml at {}" , path. display ( ) ) ) ?
421+ Err ( WorkspaceError :: CargoTomlNotFound ( path. to_path_buf ( ) ) )
366422}
367423
368424pub fn get_rustc_cfg_options ( ) -> CfgOptions {
@@ -376,13 +432,16 @@ pub fn get_rustc_cfg_options() -> CfgOptions {
376432 }
377433 }
378434
379- match ( || -> Result < _ > {
435+ match ( || -> Result < _ , WorkspaceError > {
380436 // `cfg(test)` and `cfg(debug_assertion)` are handled outside, so we suppress them here.
381- let output = Command :: new ( "rustc" ) . args ( & [ "--print" , "cfg" , "-O" ] ) . output ( ) ?;
437+ let output = Command :: new ( "rustc" )
438+ . args ( & [ "--print" , "cfg" , "-O" ] )
439+ . output ( )
440+ . map_err ( |err| WorkspaceError :: RustcError ( err) ) ?;
382441 if !output. status . success ( ) {
383- Err ( "failed to get rustc cfgs" ) ?;
442+ Err ( WorkspaceError :: RustcCfgError ) ?;
384443 }
385- Ok ( String :: from_utf8 ( output. stdout ) ?)
444+ Ok ( String :: from_utf8 ( output. stdout ) . map_err ( |err| WorkspaceError :: RustcOutputError ( err ) ) ?)
386445 } ) ( ) {
387446 Ok ( rustc_cfgs) => {
388447 for line in rustc_cfgs. lines ( ) {
0 commit comments