@@ -25,7 +25,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
2525use std:: env;
2626use std:: ffi:: OsString ;
2727use std:: fs:: { read_dir, remove_file} ;
28- use std:: path:: Path ;
28+ use std:: path:: { Path , PathBuf } ;
2929use std:: process:: Command ;
3030use std:: sync:: { Arc , Mutex } ;
3131use std:: thread;
@@ -64,10 +64,10 @@ pub(super) fn cargo(internals: &Internals) -> BuildResult {
6464
6565 match handle
6666 . join ( )
67- . map_err ( |_| "thread panicked" . into ( ) )
67+ . map_err ( |_| format_err ! ( "thread panicked" ) )
6868 . and_then ( |res| res)
6969 {
70- Ok ( _ ) if workspace_mode => {
70+ Ok ( ref cwd ) if workspace_mode => {
7171 let diagnostics = Arc :: try_unwrap ( diagnostics_clone)
7272 . unwrap ( )
7373 . into_inner ( )
@@ -76,9 +76,9 @@ pub(super) fn cargo(internals: &Internals) -> BuildResult {
7676 . unwrap ( )
7777 . into_inner ( )
7878 . unwrap ( ) ;
79- BuildResult :: Success ( diagnostics, analysis)
79+ BuildResult :: Success ( cwd . clone ( ) , diagnostics, analysis)
8080 }
81- Ok ( _ ) => BuildResult :: Success ( vec ! [ ] , vec ! [ ] ) ,
81+ Ok ( cwd ) => BuildResult :: Success ( cwd , vec ! [ ] , vec ! [ ] ) ,
8282 Err ( err) => {
8383 let stdout = String :: from_utf8 ( out_clone. lock ( ) . unwrap ( ) . to_owned ( ) ) . unwrap ( ) ;
8484 info ! ( "cargo failed\n cause: {}\n stdout: {}" , err, stdout) ;
@@ -95,13 +95,15 @@ fn run_cargo(
9595 compiler_messages : Arc < Mutex < Vec < String > > > ,
9696 analysis : Arc < Mutex < Vec < Analysis > > > ,
9797 out : Arc < Mutex < Vec < u8 > > > ,
98- ) -> CargoResult < ( ) > {
98+ ) -> CargoResult < PathBuf > {
9999 // Lock early to guarantee synchronized access to env var for the scope of Cargo routine.
100100 // Additionally we need to pass inner lock to RlsExecutor, since it needs to hand it down
101101 // during exec() callback when calling linked compiler in parallel, for which we need to
102102 // guarantee consistent environment variables.
103103 let ( lock_guard, inner_lock) = env_lock. lock ( ) ;
104104
105+ let mut restore_env = Environment :: push_with_lock ( & HashMap :: new ( ) , None , lock_guard) ;
106+
105107 let build_dir = {
106108 let mut compilation_cx = compilation_cx. lock ( ) . unwrap ( ) ;
107109 // Since Cargo build routine will try to regenerate the unit dep graph,
@@ -123,7 +125,7 @@ fn run_cargo(
123125 let rls_config = rls_config. lock ( ) . unwrap ( ) ;
124126
125127 let target_dir = rls_config. target_dir . as_ref ( ) . map ( |p| p as & Path ) ;
126- make_cargo_config ( manifest_dir, target_dir, shell)
128+ make_cargo_config ( manifest_dir, target_dir, restore_env . get_old_cwd ( ) , shell)
127129 } ;
128130
129131 let ws = Workspace :: new ( & manifest_path, & config) ?;
@@ -186,16 +188,14 @@ fn run_cargo(
186188 ..CompileOptions :: default ( & config, CompileMode :: Check { test : false } )
187189 } ;
188190
189- // Create a custom environment for running cargo, the environment is reset afterwards automatically
190- let mut env : HashMap < String , Option < OsString > > = HashMap :: new ( ) ;
191- env . insert ( "RUSTFLAGS" . to_owned ( ) , Some ( rustflags. into ( ) ) ) ;
191+ // Create a custom environment for running cargo, the environment is reset
192+ // afterwards automatically
193+ restore_env . push_var ( "RUSTFLAGS" , & Some ( rustflags. into ( ) ) ) ;
192194
193195 if clear_env_rust_log {
194- env . insert ( "RUST_LOG" . to_owned ( ) , None ) ;
196+ restore_env . push_var ( "RUST_LOG" , & None ) ;
195197 }
196198
197- let _restore_env = Environment :: push_with_lock ( & env, lock_guard) ;
198-
199199 let exec = RlsExecutor :: new (
200200 & ws,
201201 compilation_cx. clone ( ) ,
@@ -213,7 +213,9 @@ fn run_cargo(
213213 compilation_cx. lock( ) . unwrap( ) . build_plan
214214 ) ;
215215
216- Ok ( ( ) )
216+ Ok ( compilation_cx. lock ( ) . unwrap ( ) . cwd . clone ( ) . unwrap_or_else ( || {
217+ restore_env. get_old_cwd ( ) . to_path_buf ( )
218+ } ) )
217219}
218220
219221struct RlsExecutor {
@@ -475,11 +477,12 @@ impl Executor for RlsExecutor {
475477 & self . vfs ,
476478 & args,
477479 & envs,
480+ cargo_cmd. get_cwd ( ) ,
478481 & build_dir,
479482 self . config . clone ( ) ,
480483 env_lock,
481484 ) {
482- BuildResult :: Success ( mut messages, mut analysis) => {
485+ BuildResult :: Success ( _ , mut messages, mut analysis) => {
483486 self . compiler_messages . lock ( ) . unwrap ( ) . append ( & mut messages) ;
484487 self . analysis . lock ( ) . unwrap ( ) . append ( & mut analysis) ;
485488 }
@@ -493,6 +496,7 @@ impl Executor for RlsExecutor {
493496 let mut compilation_cx = self . compilation_cx . lock ( ) . unwrap ( ) ;
494497 compilation_cx. args = args;
495498 compilation_cx. envs = envs;
499+ compilation_cx. cwd = cargo_cmd. get_cwd ( ) . map ( |p| p. to_path_buf ( ) ) ;
496500
497501 Ok ( ( ) )
498502 }
@@ -596,13 +600,13 @@ fn prepare_cargo_rustflags(config: &Config) -> String {
596600
597601/// Construct a cargo configuration for the given build and target directories
598602/// and shell.
599- pub fn make_cargo_config ( build_dir : & Path , target_dir : Option < & Path > , shell : Shell ) -> CargoConfig {
603+ pub fn make_cargo_config ( build_dir : & Path ,
604+ target_dir : Option < & Path > ,
605+ cwd : & Path ,
606+ shell : Shell ) -> CargoConfig {
600607 let config = CargoConfig :: new (
601608 shell,
602- // This is Cargo's cwd. We're using the actual cwd,
603- // because Cargo will generate relative paths based
604- // on this to source files it wants to compile
605- env:: current_dir ( ) . unwrap ( ) ,
609+ cwd. to_path_buf ( ) ,
606610 homedir ( & build_dir) . unwrap ( ) ,
607611 ) ;
608612
0 commit comments