@@ -67,6 +67,15 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Inferrable<T> {
67
67
}
68
68
}
69
69
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
+
70
79
impl < T : Clone + Debug > Inferrable < T > {
71
80
/// Combine these inferrable values, preferring our own specified values
72
81
/// when possible, and falling back the given default value.
@@ -104,6 +113,7 @@ impl<T> AsRef<T> for Inferrable<T> {
104
113
}
105
114
}
106
115
}
116
+
107
117
/// RLS configuration options.
108
118
#[ derive( Clone , Debug , Deserialize , Serialize ) ]
109
119
#[ allow( missing_docs) ]
@@ -126,8 +136,7 @@ pub struct Config {
126
136
pub build_on_save : bool ,
127
137
pub use_crate_blacklist : bool ,
128
138
/// 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 > > ,
131
140
pub features : Vec < String > ,
132
141
pub all_features : bool ,
133
142
pub no_default_features : bool ,
@@ -156,7 +165,7 @@ impl Default for Config {
156
165
clear_env_rust_log : true ,
157
166
build_on_save : false ,
158
167
use_crate_blacklist : true ,
159
- target_dir : None ,
168
+ target_dir : Inferrable :: Inferred ( None ) ,
160
169
features : vec ! [ ] ,
161
170
all_features : false ,
162
171
no_default_features : false ,
@@ -173,6 +182,7 @@ impl Default for Config {
173
182
impl Config {
174
183
/// Join this configuration with the new config.
175
184
pub fn update ( & mut self , mut new : Config ) {
185
+ new. target_dir = self . target_dir . combine_with_default ( & new. target_dir , None ) ;
176
186
new. build_lib = self . build_lib . combine_with_default ( & new. build_lib , false ) ;
177
187
new. build_bin = self . build_bin . combine_with_default ( & new. build_bin , None ) ;
178
188
@@ -203,10 +213,9 @@ impl Config {
203
213
204
214
/// Is this config incomplete, and needs additional values to be inferred?
205
215
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 ( )
210
219
}
211
220
212
221
/// Tries to auto-detect certain option values if they were unspecified.
@@ -232,13 +241,21 @@ impl Config {
232
241
// Constructing a `Workspace` also probes the filesystem and detects where to place the
233
242
// build artifacts. We need to rely on Cargo's behaviour directly not to possibly place our
234
243
// 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 ( ) {
236
252
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) ) ;
238
255
trace ! (
239
256
"For project path {:?} Cargo told us to use this target/ dir: {:?}" ,
240
257
project_dir,
241
- self . target_dir. as_ref( ) . unwrap( ) ,
258
+ self . target_dir. as_ref( ) . as_ref ( ) . unwrap( ) ,
242
259
) ;
243
260
}
244
261
0 commit comments