@@ -67,6 +67,15 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Inferrable<T> {
6767 }
6868}
6969
70+ impl < T > Inferrable < T > {
71+ pub fn is_none ( & self ) -> bool {
72+ match * self {
73+ Inferrable :: None => true ,
74+ _ => false ,
75+ }
76+ }
77+ }
78+
7079impl < T : Clone + Debug > Inferrable < T > {
7180 /// Combine these inferrable values, preferring our own specified values
7281 /// when possible, and falling back the given default value.
@@ -104,6 +113,7 @@ impl<T> AsRef<T> for Inferrable<T> {
104113 }
105114 }
106115}
116+
107117/// RLS configuration options.
108118#[ derive( Clone , Debug , Deserialize , Serialize ) ]
109119#[ allow( missing_docs) ]
@@ -126,8 +136,7 @@ pub struct Config {
126136 pub build_on_save : bool ,
127137 pub use_crate_blacklist : bool ,
128138 /// Cargo target dir. If set overrides the default one.
129- #[ serde( skip_deserializing, skip_serializing) ]
130- pub target_dir : Option < PathBuf > ,
139+ pub target_dir : Inferrable < Option < PathBuf > > ,
131140 pub features : Vec < String > ,
132141 pub all_features : bool ,
133142 pub no_default_features : bool ,
@@ -156,7 +165,7 @@ impl Default for Config {
156165 clear_env_rust_log : true ,
157166 build_on_save : false ,
158167 use_crate_blacklist : true ,
159- target_dir : None ,
168+ target_dir : Inferrable :: Inferred ( None ) ,
160169 features : vec ! [ ] ,
161170 all_features : false ,
162171 no_default_features : false ,
@@ -173,6 +182,7 @@ impl Default for Config {
173182impl Config {
174183 /// Join this configuration with the new config.
175184 pub fn update ( & mut self , mut new : Config ) {
185+ new. target_dir = self . target_dir . combine_with_default ( & new. target_dir , None ) ;
176186 new. build_lib = self . build_lib . combine_with_default ( & new. build_lib , false ) ;
177187 new. build_bin = self . build_bin . combine_with_default ( & new. build_bin , None ) ;
178188
@@ -203,10 +213,9 @@ impl Config {
203213
204214 /// Is this config incomplete, and needs additional values to be inferred?
205215 pub fn needs_inference ( & self ) -> bool {
206- match ( & self . build_lib , & self . build_bin ) {
207- ( & Inferrable :: None , _) | ( _, & Inferrable :: None ) => true ,
208- _ => false ,
209- }
216+ self . build_bin . is_none ( ) ||
217+ self . build_lib . is_none ( ) ||
218+ self . target_dir . is_none ( )
210219 }
211220
212221 /// Tries to auto-detect certain option values if they were unspecified.
@@ -232,13 +241,21 @@ impl Config {
232241 // Constructing a `Workspace` also probes the filesystem and detects where to place the
233242 // build artifacts. We need to rely on Cargo's behaviour directly not to possibly place our
234243 // own artifacts somewhere else (e.g. when analyzing only a single crate in a workspace)
235- if self . target_dir . is_none ( ) {
244+ match self . target_dir {
245+ // We require an absolute path, so adjust a relative one if it's passed.
246+ Inferrable :: Specified ( Some ( ref mut path) ) if path. is_relative ( ) => {
247+ * path = project_dir. join ( & path) ;
248+ }
249+ _ => { } ,
250+ }
251+ if self . target_dir . as_ref ( ) . is_none ( ) {
236252 let target_dir = ws. target_dir ( ) . clone ( ) . into_path_unlocked ( ) ;
237- self . target_dir = Some ( target_dir) ;
253+ let target_dir = target_dir. join ( "rls" ) ;
254+ self . target_dir . infer ( Some ( target_dir) ) ;
238255 trace ! (
239256 "For project path {:?} Cargo told us to use this target/ dir: {:?}" ,
240257 project_dir,
241- self . target_dir. as_ref( ) . unwrap( ) ,
258+ self . target_dir. as_ref( ) . as_ref ( ) . unwrap( ) ,
242259 ) ;
243260 }
244261
0 commit comments