8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use cargo:: core:: { PackageId , Shell , Target , Workspace , Verbosity } ;
11
+ use cargo:: core:: { PackageId , Shell , Target , TargetKind , Workspace , Verbosity } ;
12
12
use cargo:: ops:: { compile_with_exec, Executor , Context , Packages , CompileOptions , CompileMode , CompileFilter , Unit } ;
13
13
use cargo:: util:: { Config as CargoConfig , ProcessBuilder , homedir, important_paths, ConfigValue , CargoResult } ;
14
- use cargo:: util:: errors:: { CargoErrorKind , process_error} ;
15
14
use serde_json;
16
15
17
16
use data:: Analysis ;
@@ -269,7 +268,7 @@ impl Executor for RlsExecutor {
269
268
self . is_primary_crate ( id)
270
269
}
271
270
272
- fn exec ( & self , cargo_cmd : ProcessBuilder , id : & PackageId , _target : & Target ) -> CargoResult < ( ) > {
271
+ fn exec ( & self , cargo_cmd : ProcessBuilder , id : & PackageId , target : & Target ) -> CargoResult < ( ) > {
273
272
// Delete any stale data. We try and remove any json files with
274
273
// the same crate name as Cargo would emit. This includes files
275
274
// with the same crate name but different hashes, e.g., those
@@ -294,37 +293,25 @@ impl Executor for RlsExecutor {
294
293
}
295
294
}
296
295
297
- let rustc_exe = env :: var ( " RUSTC" ) . unwrap_or ( env :: args ( ) . next ( ) . unwrap ( ) ) ;
298
- let mut cmd = Command :: new ( & rustc_exe ) ;
296
+ // Cargo should handle `$ RUSTC` wrapper override already
297
+ let mut cmd = cargo_cmd . clone ( ) ;
299
298
cmd. env ( :: RUSTC_SHIM_ENV_VAR_NAME , "1" ) ;
300
299
301
300
// We only want to intercept rustc call targeting current crate to cache
302
301
// args/envs generated by cargo so we can run only rustc later ourselves
303
302
// Currently we don't cache nor modify build script args
304
- let is_build_script = crate_name == "build_script_build" ;
303
+ let is_build_script = * target . kind ( ) == TargetKind :: CustomBuild ;
305
304
if !self . is_primary_crate ( id) || is_build_script {
306
305
let build_script_notice = if is_build_script { " (build script)" } else { "" } ;
307
306
trace ! ( "rustc not intercepted - {}{}" , id. name( ) , build_script_notice) ;
308
307
308
+ // Recreate the command, minus -Zsave-analysis.
309
309
if :: CRATE_BLACKLIST . contains ( & & * crate_name) {
310
- // Recreate the command, minus -Zsave-analysis.
311
- for a in cargo_args {
312
- if a != "-Zsave-analysis" {
313
- cmd. arg ( a) ;
314
- }
315
- }
316
- cmd. envs ( cargo_cmd. get_envs ( ) . iter ( ) . filter_map ( |( k, v) | v. as_ref ( ) . map ( |v| ( k, v) ) ) ) ;
317
- if let Some ( cwd) = cargo_cmd. get_cwd ( ) {
318
- cmd. current_dir ( cwd) ;
319
- }
320
- return match cmd. status ( ) {
321
- Ok ( ref e) if e. success ( ) => Ok ( ( ) ) ,
322
- _ => Err ( CargoErrorKind :: ProcessErrorKind ( process_error (
323
- "process didn't exit successfully" , None , None ) ) . into ( ) ) ,
324
- } ;
325
- } else {
326
- return cargo_cmd. exec ( ) ;
310
+ let args: Vec < _ > = cmd. get_args ( ) . iter ( ) . cloned ( )
311
+ . filter ( |x| x != "Zsave-analysis" ) . collect ( ) ;
312
+ cmd. args_replace ( & args) ;
327
313
}
314
+ return cmd. exec ( ) ;
328
315
}
329
316
330
317
trace ! ( "rustc intercepted - args: {:?} envs: {:?}" , cargo_args, cargo_cmd. get_envs( ) ) ;
@@ -367,25 +354,22 @@ impl Executor for RlsExecutor {
367
354
// so the dep-info is ready by the time we return from this callback.
368
355
// NB: In `workspace_mode` regular compilation is performed here (and we don't
369
356
// only calculate dep-info) so it should fix the problem mentioned above.
370
- // Since ProcessBuilder doesn't allow to modify args, we need to create
371
- // our own command here from scratch here.
372
- for a in & args {
373
- // Emitting only dep-info is possible only for final crate type, as
374
- // as others may emit required metadata for dependent crate types
375
- if a. starts_with ( "--emit" ) && is_final_crate_type && !self . workspace_mode {
376
- cmd. arg ( "--emit=dep-info" ) ;
377
- } else if a != "-Zsave-analysis" {
378
- cmd. arg ( a) ;
379
- }
380
- }
381
- cmd. envs ( cargo_cmd. get_envs ( ) . iter ( ) . filter_map ( |( k, v) | v. as_ref ( ) . map ( |v| ( k, v) ) ) ) ;
382
- if let Some ( cwd) = cargo_cmd. get_cwd ( ) {
383
- cmd. current_dir ( cwd) ;
384
- }
357
+ let modified = args. iter ( )
358
+ . filter ( |a| * a != "-Zsave-analysis" )
359
+ . map ( |a| {
360
+ // Emitting only dep-info is possible only for final crate type, as
361
+ // as others may emit required metadata for dependent crate types
362
+ if a. starts_with ( "--emit" ) && is_final_crate_type && !self . workspace_mode {
363
+ "--emit=dep-info"
364
+ } else { a }
365
+ } )
366
+ . collect :: < Vec < _ > > ( ) ;
367
+ cmd. args_replace ( & modified) ;
385
368
}
386
369
387
370
// Prepare modified cargo-generated args/envs for future rustc calls
388
- args. insert ( 0 , rustc_exe) ;
371
+ let rustc = cargo_cmd. get_program ( ) . to_owned ( ) . into_string ( ) . unwrap ( ) ;
372
+ args. insert ( 0 , rustc) ;
389
373
let envs = cargo_cmd. get_envs ( ) . clone ( ) ;
390
374
391
375
if self . workspace_mode {
@@ -405,7 +389,7 @@ impl Executor for RlsExecutor {
405
389
_ => { }
406
390
}
407
391
} else {
408
- cmd. status ( ) . expect ( "Couldn't execute rustc" ) ;
392
+ cmd. exec ( ) ? ;
409
393
}
410
394
411
395
// Finally, store the modified cargo-generated args/envs for future rustc calls
0 commit comments