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
- use cargo:: util:: { Config as CargoConfig , process_builder, ProcessBuilder , homedir, important_paths, ConfigValue , CargoResult } ;
14
- use cargo:: util:: errors:: { CargoErrorKind , process_error} ;
13
+ use cargo:: util:: { Config as CargoConfig , ProcessBuilder , homedir, important_paths, ConfigValue , CargoResult } ;
15
14
use serde_json;
16
15
17
16
use data:: Analysis ;
@@ -296,37 +295,35 @@ impl Executor for RlsExecutor {
296
295
}
297
296
}
298
297
299
- let rustc_exe = env:: var ( "RUSTC" ) . unwrap_or ( env:: args ( ) . next ( ) . unwrap ( ) ) ;
300
- let mut cmd = Command :: new ( & rustc_exe) ;
298
+ // Prepare our own call to `rustc` as follows:
299
+ // 1. Use $RUSTC wrapper if specified, otherwise use RLS executable
300
+ // as an rustc shim (needed to distribute via the stable channel)
301
+ // 2. For non-primary packages or build scripts, execute the call
302
+ // 3. Otherwise, we'll want to use the compilation to drive the analysis:
303
+ // i. Modify arguments to account for the RLS settings (e.g.
304
+ // compiling under cfg(test) mode or passing a custom sysroot)
305
+ // ii. Execute the call and store the final args/envs to be used for
306
+ // later in-process execution of the compiler
307
+ let mut cmd = cargo_cmd. clone ( ) ;
308
+ let rls_executable = env:: args ( ) . next ( ) . unwrap ( ) ;
309
+ cmd. program ( env:: var ( "RUSTC" ) . unwrap_or ( rls_executable) ) ;
301
310
cmd. env ( :: RUSTC_SHIM_ENV_VAR_NAME , "1" ) ;
302
311
303
312
// We only want to intercept rustc call targeting current crate to cache
304
313
// args/envs generated by cargo so we can run only rustc later ourselves
305
314
// Currently we don't cache nor modify build script args
306
- let is_build_script = crate_name == "build_script_build" ;
315
+ let is_build_script = * target . kind ( ) == TargetKind :: CustomBuild ;
307
316
if !self . is_primary_crate ( id) || is_build_script {
308
317
let build_script_notice = if is_build_script { " (build script)" } else { "" } ;
309
318
trace ! ( "rustc not intercepted - {}{}" , id. name( ) , build_script_notice) ;
310
319
320
+ // Recreate the command, minus -Zsave-analysis.
311
321
if :: CRATE_BLACKLIST . contains ( & & * crate_name) {
312
- // Recreate the command, minus -Zsave-analysis.
313
- for a in cargo_args {
314
- if a != "-Zsave-analysis" {
315
- cmd. arg ( a) ;
316
- }
317
- }
318
- cmd. envs ( cargo_cmd. get_envs ( ) . iter ( ) . filter_map ( |( k, v) | v. as_ref ( ) . map ( |v| ( k, v) ) ) ) ;
319
- if let Some ( cwd) = cargo_cmd. get_cwd ( ) {
320
- cmd. current_dir ( cwd) ;
321
- }
322
- return match cmd. status ( ) {
323
- Ok ( ref e) if e. success ( ) => Ok ( ( ) ) ,
324
- _ => Err ( CargoErrorKind :: ProcessErrorKind ( process_error (
325
- "process didn't exit successfully" , None , None ) ) . into ( ) ) ,
326
- } ;
327
- } else {
328
- return cargo_cmd. exec ( ) ;
322
+ let args: Vec < _ > = cmd. get_args ( ) . iter ( ) . cloned ( )
323
+ . filter ( |x| x != "Zsave-analysis" ) . collect ( ) ;
324
+ cmd. args_replace ( & args) ;
329
325
}
326
+ return cmd. exec ( ) ;
330
327
}
331
328
332
329
trace ! ( "rustc intercepted - args: {:?} envs: {:?}" , cargo_args, cargo_cmd. get_envs( ) ) ;
@@ -369,43 +366,28 @@ impl Executor for RlsExecutor {
369
366
// so the dep-info is ready by the time we return from this callback.
370
367
// NB: In `workspace_mode` regular compilation is performed here (and we don't
371
368
// only calculate dep-info) so it should fix the problem mentioned above.
372
- // Since ProcessBuilder doesn't allow to modify args, we need to create
373
- // our own command here from scratch here.
374
- for a in & args {
375
- // Emitting only dep-info is possible only for final crate type, as
376
- // as others may emit required metadata for dependent crate types
377
- if a. starts_with ( "--emit" ) && is_final_crate_type && !self . workspace_mode {
378
- cmd. arg ( "--emit=dep-info" ) ;
379
- } else if a != "-Zsave-analysis" {
380
- cmd. arg ( a) ;
381
- }
382
- }
383
- cmd. envs ( cargo_cmd. get_envs ( ) . iter ( ) . filter_map ( |( k, v) | v. as_ref ( ) . map ( |v| ( k, v) ) ) ) ;
384
- if let Some ( cwd) = cargo_cmd. get_cwd ( ) {
385
- cmd. current_dir ( cwd) ;
386
- }
369
+ let modified = args. iter ( )
370
+ . filter ( |a| * a != "-Zsave-analysis" )
371
+ . map ( |a| {
372
+ // Emitting only dep-info is possible only for final crate type, as
373
+ // as others may emit required metadata for dependent crate types
374
+ if a. starts_with ( "--emit" ) && is_final_crate_type && !self . workspace_mode {
375
+ "--emit=dep-info"
376
+ } else { a }
377
+ } )
378
+ . collect :: < Vec < _ > > ( ) ;
379
+ cmd. args_replace ( & modified) ;
387
380
}
388
381
389
382
// Cache executed command for the build plan
390
383
{
391
384
let mut cx = self . compilation_cx . lock ( ) . unwrap ( ) ;
392
-
393
- let mut store_cmd = process_builder:: process ( & rustc_exe) ;
394
- store_cmd. args ( & args. iter ( ) . map ( OsString :: from) . collect :: < Vec < _ > > ( ) ) ;
395
- for ( k, v) in cargo_cmd. get_envs ( ) . clone ( ) {
396
- if let Some ( v) = v {
397
- store_cmd. env ( & k, v) ;
398
- }
399
- }
400
- if let Some ( cwd) = cargo_cmd. get_cwd ( ) {
401
- cmd. current_dir ( cwd) ;
402
- }
403
-
404
- cx. build_plan . cache_compiler_job ( id, target, & store_cmd) ;
385
+ cx. build_plan . cache_compiler_job ( id, target, & cmd) ;
405
386
}
406
387
407
388
// Prepare modified cargo-generated args/envs for future rustc calls
408
- args. insert ( 0 , rustc_exe) ;
389
+ let rustc = cargo_cmd. get_program ( ) . to_owned ( ) . into_string ( ) . unwrap ( ) ;
390
+ args. insert ( 0 , rustc) ;
409
391
let envs = cargo_cmd. get_envs ( ) . clone ( ) ;
410
392
411
393
if self . workspace_mode {
@@ -425,7 +407,7 @@ impl Executor for RlsExecutor {
425
407
_ => { }
426
408
}
427
409
} else {
428
- cmd. status ( ) . expect ( "Couldn't execute rustc" ) ;
410
+ cmd. exec ( ) ? ;
429
411
}
430
412
431
413
// Finally, store the modified cargo-generated args/envs for future rustc calls
0 commit comments