@@ -5,15 +5,15 @@ mod json_project;
5
5
mod sysroot;
6
6
7
7
use std:: {
8
- error :: Error ,
8
+ fmt ,
9
9
fs:: File ,
10
10
io:: BufReader ,
11
11
path:: { Path , PathBuf } ,
12
12
process:: Command ,
13
13
} ;
14
14
15
15
use ra_cfg:: CfgOptions ;
16
- use ra_db:: { CrateGraph , CrateId , Edition , Env , FileId } ;
16
+ use ra_db:: { CrateGraph , CrateId , Edition , Env , FileId , ParseEditionError } ;
17
17
use rustc_hash:: FxHashMap ;
18
18
use serde_json:: from_reader;
19
19
@@ -23,8 +23,57 @@ pub use crate::{
23
23
sysroot:: Sysroot ,
24
24
} ;
25
25
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
+ }
28
77
29
78
#[ derive( Debug , Clone ) ]
30
79
pub enum ProjectWorkspace {
@@ -60,20 +109,27 @@ impl PackageRoot {
60
109
}
61
110
62
111
impl 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 > {
64
116
ProjectWorkspace :: discover_with_sysroot ( path, true , cargo_features)
65
117
}
66
118
67
119
pub fn discover_with_sysroot (
68
120
path : & Path ,
69
121
with_sysroot : bool ,
70
122
cargo_features : & CargoFeatures ,
71
- ) -> Result < ProjectWorkspace > {
123
+ ) -> Result < ProjectWorkspace , WorkspaceError > {
72
124
match find_rust_project_json ( path) {
73
125
Some ( json_path) => {
74
- let file = File :: open ( json_path) ?;
126
+ let file =
127
+ File :: open ( json_path) . map_err ( |err| WorkspaceError :: OpenWorkspaceError ( err) ) ?;
75
128
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
+ } )
77
133
}
78
134
None => {
79
135
let cargo_toml = find_cargo_toml ( path) ?;
@@ -350,7 +406,7 @@ fn find_rust_project_json(path: &Path) -> Option<PathBuf> {
350
406
None
351
407
}
352
408
353
- fn find_cargo_toml ( path : & Path ) -> Result < PathBuf > {
409
+ fn find_cargo_toml ( path : & Path ) -> Result < PathBuf , WorkspaceError > {
354
410
if path. ends_with ( "Cargo.toml" ) {
355
411
return Ok ( path. to_path_buf ( ) ) ;
356
412
}
@@ -362,7 +418,7 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
362
418
}
363
419
curr = path. parent ( ) ;
364
420
}
365
- Err ( format ! ( "can't find Cargo.toml at {}" , path. display ( ) ) ) ?
421
+ Err ( WorkspaceError :: CargoTomlNotFound ( path. to_path_buf ( ) ) )
366
422
}
367
423
368
424
pub fn get_rustc_cfg_options ( ) -> CfgOptions {
@@ -376,13 +432,16 @@ pub fn get_rustc_cfg_options() -> CfgOptions {
376
432
}
377
433
}
378
434
379
- match ( || -> Result < _ > {
435
+ match ( || -> Result < _ , WorkspaceError > {
380
436
// `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) ) ?;
382
441
if !output. status . success ( ) {
383
- Err ( "failed to get rustc cfgs" ) ?;
442
+ Err ( WorkspaceError :: RustcCfgError ) ?;
384
443
}
385
- Ok ( String :: from_utf8 ( output. stdout ) ?)
444
+ Ok ( String :: from_utf8 ( output. stdout ) . map_err ( |err| WorkspaceError :: RustcOutputError ( err ) ) ?)
386
445
} ) ( ) {
387
446
Ok ( rustc_cfgs) => {
388
447
for line in rustc_cfgs. lines ( ) {
0 commit comments