@@ -18,8 +18,7 @@ extern crate syntax;
18
18
19
19
use cargo:: core:: { PackageId , Shell , Workspace , Verbosity } ;
20
20
use cargo:: ops:: { compile_with_exec, Executor , Context , Packages , CompileOptions , CompileMode , CompileFilter , Unit } ;
21
- use cargo:: util:: { Config as CargoConfig , ProcessBuilder , homedir, ConfigValue } ;
22
- use cargo:: util:: { CargoResult , important_paths} ;
21
+ use cargo:: util:: { Config as CargoConfig , ProcessBuilder , homedir, important_paths, ConfigValue , CargoResult } ;
23
22
24
23
use data:: Analysis ;
25
24
use vfs:: Vfs ;
@@ -256,7 +255,7 @@ impl BuildQueue {
256
255
let result = self . cargo ( build_dir. clone ( ) ) ;
257
256
258
257
match result {
259
- BuildResult :: Err |
258
+ BuildResult :: Err => return BuildResult :: Err ,
260
259
_ if workspace_mode => return result,
261
260
_ => { } ,
262
261
} ;
@@ -275,23 +274,25 @@ impl BuildQueue {
275
274
compilation_cx : Arc < Mutex < CompilationContext > > ,
276
275
cur_package_id : Mutex < Option < PackageId > > ,
277
276
config : Arc < Mutex < Config > > ,
278
- /// Packages which are directly a member of the workspace, currently
279
- /// RLS shouldn't provide analysis for upstream packages to those
280
277
workspace_mode : bool ,
278
+ /// Packages which are directly a member of the workspace, for which
279
+ /// analysis and diagnostics will be provided
281
280
member_packages : Mutex < HashSet < PackageId > > ,
282
281
/// JSON compiler messages emitted for each primary compiled crate
283
282
compiler_messages : Arc < Mutex < Vec < String > > > ,
284
283
}
285
284
286
285
impl RlsExecutor {
287
286
fn new ( compilation_cx : Arc < Mutex < CompilationContext > > ,
288
- config : Arc < Mutex < Config > > , compiler_messages : Arc < Mutex < Vec < String > > > )
289
- -> RlsExecutor {
287
+ config : Arc < Mutex < Config > > ,
288
+ compiler_messages : Arc < Mutex < Vec < String > > > )
289
+ -> RlsExecutor {
290
+ let workspace_mode = config. lock ( ) . unwrap ( ) . workspace_mode ;
290
291
RlsExecutor {
291
- compilation_cx : compilation_cx ,
292
+ compilation_cx,
292
293
cur_package_id : Mutex :: new ( None ) ,
293
294
config,
294
- workspace_mode : config . lock ( ) . unwrap ( ) . workspace_mode ,
295
+ workspace_mode,
295
296
member_packages : Mutex :: new ( HashSet :: new ( ) ) ,
296
297
compiler_messages,
297
298
}
@@ -303,7 +304,7 @@ impl BuildQueue {
303
304
} else {
304
305
let cur_package_id = self . cur_package_id . lock ( ) . unwrap ( ) ;
305
306
id == cur_package_id. as_ref ( ) . expect ( "Executor has not been initialised" )
306
- } ;
307
+ }
307
308
}
308
309
}
309
310
@@ -417,7 +418,9 @@ impl BuildQueue {
417
418
for a in & args {
418
419
// Emitting only dep-info is possible only for final crate type, as
419
420
// as others may emit required metadata for dependent crate types
420
- if a. starts_with ( "--emit" ) && is_final_crate_type && !workspace_mode {
421
+ // In workspace_mode we don't run follow-up rustc, so don't omit anything,
422
+ // as we need the generated save-analysis file
423
+ if a. starts_with ( "--emit" ) && is_final_crate_type && !self . workspace_mode {
421
424
cmd. arg ( "--emit=dep-info" ) ;
422
425
} else {
423
426
cmd. arg ( a) ;
@@ -429,8 +432,7 @@ impl BuildQueue {
429
432
}
430
433
}
431
434
432
- // Different path for workspace_mode just to be 110% sure it doesn't affect old behaviour
433
- if workspace_mode {
435
+ if self . workspace_mode {
434
436
let output = cmd. output ( ) . expect ( "Couldn't execute rustc" ) ;
435
437
let mut stderr_json_msg = convert_message_to_json_strings ( output. stderr ) ;
436
438
self . compiler_messages . lock ( ) . unwrap ( ) . append ( & mut stderr_json_msg) ;
@@ -464,64 +466,27 @@ impl BuildQueue {
464
466
// However, if Cargo doesn't run a separate thread, then we'll just wait
465
467
// forever. Therefore, we spawn an extra thread here to be safe.
466
468
let handle = thread:: spawn ( move || {
467
- #[ allow( dead_code) ]
468
469
#[ derive( Debug ) ]
469
470
struct CargoOptions {
470
- flag_package : Vec < String > ,
471
- flag_jobs : Option < u32 > ,
472
- flag_features : Vec < String > ,
473
- flag_all_features : bool ,
474
- flag_no_default_features : bool ,
475
- flag_target : Option < String > ,
476
- flag_manifest_path : Option < String > ,
477
- flag_verbose : u32 ,
478
- flag_quiet : Option < bool > ,
479
- flag_color : Option < String > ,
480
- //flag_message_format: MessageFormat,
481
- flag_release : bool ,
482
- flag_lib : bool ,
483
- flag_bin : Vec < String > ,
484
- flag_bins : bool ,
485
- flag_example : Vec < String > ,
486
- flag_examples : bool ,
487
- flag_test : Vec < String > ,
488
- flag_tests : bool ,
489
- flag_bench : Vec < String > ,
490
- flag_benches : bool ,
491
- flag_locked : bool ,
492
- flag_frozen : bool ,
493
- flag_all : bool ,
494
- flag_exclude : Vec < String > ,
471
+ package : Vec < String > ,
472
+ target : Option < String > ,
473
+ lib : bool ,
474
+ bin : Vec < String > ,
475
+ bins : bool ,
476
+ all : bool ,
477
+ exclude : Vec < String > ,
495
478
}
496
479
497
480
impl CargoOptions {
498
481
fn default ( ) -> CargoOptions {
499
482
CargoOptions {
500
- flag_package : vec ! [ ] ,
501
- flag_jobs : None ,
502
- flag_features : vec ! [ ] ,
503
- flag_all_features : false ,
504
- flag_no_default_features : false ,
505
- flag_target : None ,
506
- flag_manifest_path : None ,
507
- flag_verbose : 0 , // u32?
508
- flag_quiet : None ,
509
- flag_color : None ,
510
- //flag_message_format: MessageFormat::Human,
511
- flag_release : false ,
512
- flag_lib : false ,
513
- flag_bin : vec ! [ ] ,
514
- flag_bins : false ,
515
- flag_example : vec ! [ ] ,
516
- flag_examples : false ,
517
- flag_test : vec ! [ ] ,
518
- flag_tests : false ,
519
- flag_bench : vec ! [ ] ,
520
- flag_benches : false ,
521
- flag_locked : false ,
522
- flag_frozen : false ,
523
- flag_all : false ,
524
- flag_exclude : vec ! [ ] ,
483
+ package : vec ! [ ] ,
484
+ target : None ,
485
+ lib : false ,
486
+ bin : vec ! [ ] ,
487
+ bins : false ,
488
+ all : false ,
489
+ exclude : vec ! [ ] ,
525
490
}
526
491
}
527
492
@@ -533,13 +498,13 @@ impl BuildQueue {
533
498
} ;
534
499
535
500
CargoOptions {
536
- flag_package : package,
537
- flag_all : all,
538
- flag_target : config. target . clone ( ) ,
501
+ package,
502
+ all,
503
+ target : config. target . clone ( ) ,
539
504
.. CargoOptions :: default ( )
540
505
}
541
506
} else {
542
- // In non-workspace mode we currently support only one crate target,
507
+ // In single-crate mode we currently support only one crate target,
543
508
// and if lib is set, then we ignore bin target config
544
509
let ( lib, bin) = match config. build_lib {
545
510
true => ( true , vec ! [ ] ) ,
@@ -553,70 +518,92 @@ impl BuildQueue {
553
518
} ;
554
519
555
520
CargoOptions {
556
- flag_lib : lib,
557
- flag_bin : bin,
558
- flag_target : config. target . clone ( ) ,
521
+ lib,
522
+ bin,
523
+ target : config. target . clone ( ) ,
559
524
.. CargoOptions :: default ( )
560
525
}
561
526
}
562
527
}
563
528
}
564
529
530
+ fn prepare_cargo_rustflags ( config : & Config ) -> String {
531
+ let mut flags = "-Zunstable-options -Zsave-analysis --error-format=json \
532
+ -Zcontinue-parse-after-error". to_owned ( ) ;
533
+
534
+ if let Some ( ref sysroot) = config. sysroot {
535
+ flags. push_str ( & format ! ( " --sysroot {}" , sysroot) ) ;
536
+ }
537
+
538
+ flags = format ! ( "{} {} {}" ,
539
+ env:: var( "RUSTFLAGS" ) . unwrap_or( String :: new( ) ) ,
540
+ config. rustflags. as_ref( ) . unwrap_or( & String :: new( ) ) ,
541
+ flags) ;
542
+
543
+ dedup_flags ( & flags)
544
+ }
545
+
565
546
// Note that this may not be equal build_dir when inside a workspace member
566
547
let manifest_path = important_paths:: find_root_manifest_for_wd ( None , & build_dir)
567
548
. expect ( & format ! ( "Couldn't find a root manifest for cwd: {:?}" , & build_dir) ) ;
568
549
trace ! ( "root manifest_path: {:?}" , & manifest_path) ;
569
550
570
551
let mut shell = Shell :: from_write ( Box :: new ( BufWriter ( out. clone ( ) ) ) ) ;
571
552
shell. set_verbosity ( Verbosity :: Quiet ) ;
572
- // We construct relative paths from the manifest dir, so we have to omit the filename
573
- let config = make_cargo_config ( manifest_path. parent ( ) . unwrap ( ) , shell) ;
553
+
554
+ // Cargo constructs relative paths from the manifest dir, so we have to pop "Cargo.toml"
555
+ let manifest_dir = manifest_path. parent ( ) . unwrap ( ) ;
556
+ let config = make_cargo_config ( manifest_dir, shell) ;
574
557
575
558
let ws = Workspace :: new ( & manifest_path, & config) . expect ( "could not create cargo workspace" ) ;
576
559
577
- // Copy over relevant options without locking whole config, as compilation procedure
578
- // will need those and we don't want to lock whole config file during that period
579
- // TODO: Keep this structure cached and regenerate it on every relevant configuration change
580
- let rls_config = rls_config. lock ( ) . unwrap ( ) . clone ( ) ;
560
+ // TODO: It might be feasible to keep this CargoOptions structure cached and regenerate
561
+ // it on every relevant configuration change
562
+ let ( opts, rustflags) = {
563
+ // We mustn't lock configuration for the whole build process
564
+ let rls_config = rls_config. lock ( ) . unwrap ( ) ;
581
565
582
- let opts = CargoOptions :: new ( & rls_config) ;
583
- trace ! ( "Current Cargo compilation options:\n {:?}" , opts) ;
566
+ let opts = CargoOptions :: new ( & rls_config) ;
567
+ trace ! ( "Cargo compilation options:\n {:?}" , opts) ;
584
568
585
- let spec = Packages :: from_flags ( opts. flag_all , & opts. flag_exclude , & opts. flag_package )
569
+ // Warn about invalid specified bin target or package depending on current mode
570
+ // TODO: Return client notifications along with diagnostics to inform the user
571
+ if !rls_config. workspace_mode {
572
+ let cur_pkg_targets = ws. current ( ) . unwrap ( ) . targets ( ) ;
573
+
574
+ if let Some ( ref build_bin) = rls_config. build_bin {
575
+ let mut bins = cur_pkg_targets. iter ( ) . filter ( |x| x. is_bin ( ) ) ;
576
+ if let None = bins. find ( |x| x. name ( ) == build_bin) {
577
+ warn ! ( "cargo - couldn't find binary `{}` specified in \" build_bin\" configuration" , build_bin) ;
578
+ }
579
+ }
580
+ } else {
581
+ for package in & opts. package {
582
+ if let None = ws. members ( ) . find ( |x| x. name ( ) == package) {
583
+ warn ! ( "cargo - couldn't find member package `{}` specified in \" analyze_package\" configuration" , package) ;
584
+ }
585
+ }
586
+ }
587
+
588
+ let rustflags = prepare_cargo_rustflags ( & rls_config) ;
589
+ ( opts, rustflags)
590
+ } ;
591
+
592
+ let spec = Packages :: from_flags ( opts. all , & opts. exclude , & opts. package )
586
593
. expect ( "Couldn't create Packages for Cargo" ) ;
587
594
588
595
let compile_opts = CompileOptions {
589
- target : opts. flag_target . as_ref ( ) . map ( |t| & t[ ..] ) ,
596
+ target : opts. target . as_ref ( ) . map ( |t| & t[ ..] ) ,
590
597
spec : spec,
591
- filter : CompileFilter :: new ( opts. flag_lib ,
592
- & opts. flag_bin , opts. flag_bins ,
593
- // TODO: Support more crate target types
594
- & [ ] , false , & [ ] , false , & [ ] , false ) ,
598
+ filter : CompileFilter :: new ( opts. lib ,
599
+ & opts. bin , opts. bins ,
600
+ // TODO: Support more crate target types
601
+ & [ ] , false , & [ ] , false , & [ ] , false ) ,
595
602
.. CompileOptions :: default ( & config, CompileMode :: Check )
596
603
} ;
597
-
598
-
599
- let rustflags = {
600
- let mut flags = "-Zunstable-options -Zsave-analysis --error-format=json \
601
- -Zcontinue-parse-after-error". to_owned ( ) ;
602
-
603
- // TODO: Needed? since it's also pushed in exec()
604
- if let Some ( ref sysroot) = rls_config. sysroot {
605
- flags. push_str ( & format ! ( " --sysroot {}" , sysroot) ) ;
606
- }
607
-
608
- flags = format ! ( "{} {} {}" ,
609
- env:: var( "RUSTFLAGS" ) . unwrap_or( String :: new( ) ) ,
610
- rls_config. rustflags. as_ref( ) . unwrap_or( & String :: new( ) ) ,
611
- flags) ;
612
-
613
- dedup_flags ( & flags)
614
- } ;
604
+
615
605
env:: set_var ( "RUSTFLAGS" , rustflags) ;
616
606
617
- // let current_package = ws.current().unwrap();
618
- // let targets = current_package.targets();
619
-
620
607
compile_with_exec ( & ws, & compile_opts, Arc :: new ( exec) ) . expect ( "could not run cargo" ) ;
621
608
} ) ;
622
609
0 commit comments