Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit f44b74d

Browse files
authored
Merge pull request #635 from alexcrichton/update-cargo
Update cargo
2 parents 0b0d31b + 4269da4 commit f44b74d

File tree

11 files changed

+117
-50
lines changed

11 files changed

+117
-50
lines changed

Cargo.lock

Lines changed: 36 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ build = "build.rs"
1212
[dependencies]
1313
cargo = { git = "https://github.com/rust-lang/cargo" }
1414
env_logger = "0.4"
15+
failure = "0.1.1"
1516
jsonrpc-core = "7.0.1"
1617
languageserver-types = "0.16"
1718
lazy_static = "0.2"

src/actions/post_build.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,19 @@ impl PostBuildHandler {
5656
self.notifier.notify_begin();
5757

5858
match result {
59-
BuildResult::Success(messages, new_analysis) => {
59+
BuildResult::Success(cwd, messages, new_analysis) => {
6060
thread::spawn(move || {
6161
trace!("build - Success");
6262

6363
// Emit appropriate diagnostics using the ones from build.
64-
self.handle_messages(messages);
64+
self.handle_messages(&cwd, messages);
6565

6666
// Reload the analysis data.
6767
debug!("reload analysis: {:?}", self.project_path);
6868
if new_analysis.is_empty() {
69-
self.reload_analysis_from_disk();
69+
self.reload_analysis_from_disk(&cwd);
7070
} else {
71-
self.reload_analysis_from_memory(new_analysis);
71+
self.reload_analysis_from_memory(&cwd, new_analysis);
7272
}
7373

7474
// Wake up any threads blocked on this analysis.
@@ -90,7 +90,7 @@ impl PostBuildHandler {
9090
}
9191
}
9292

93-
fn handle_messages(&self, messages: Vec<String>) {
93+
fn handle_messages(&self, cwd: &Path, messages: Vec<String>) {
9494
// These notifications will include empty sets of errors for files
9595
// which had errors, but now don't. This instructs the IDE to clear
9696
// errors for those files.
@@ -101,8 +101,6 @@ impl PostBuildHandler {
101101
v.clear();
102102
}
103103

104-
let cwd = ::std::env::current_dir().unwrap();
105-
106104
for msg in &messages {
107105
if let Some(FileDiagnostic {
108106
file_path,
@@ -119,8 +117,7 @@ impl PostBuildHandler {
119117
self.emit_notifications(&results);
120118
}
121119

122-
fn reload_analysis_from_disk(&self) {
123-
let cwd = ::std::env::current_dir().unwrap();
120+
fn reload_analysis_from_disk(&self, cwd: &Path) {
124121
if self.use_black_list {
125122
self.analysis
126123
.reload_with_blacklist(&self.project_path, &cwd, &CRATE_BLACKLIST)
@@ -130,8 +127,7 @@ impl PostBuildHandler {
130127
}
131128
}
132129

133-
fn reload_analysis_from_memory(&self, analysis: Vec<Analysis>) {
134-
let cwd = ::std::env::current_dir().unwrap();
130+
fn reload_analysis_from_memory(&self, cwd: &Path, analysis: Vec<Analysis>) {
135131
if self.use_black_list {
136132
self.analysis
137133
.reload_from_analysis(analysis, &self.project_path, &cwd, &CRATE_BLACKLIST)

src/build/cargo.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
2525
use std::env;
2626
use std::ffi::OsString;
2727
use std::fs::{read_dir, remove_file};
28-
use std::path::Path;
28+
use std::path::{Path, PathBuf};
2929
use std::process::Command;
3030
use std::sync::{Arc, Mutex};
3131
use 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\ncause: {}\nstdout: {}", 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

219221
struct 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

src/build/environment.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::collections::HashMap;
1112
use std::env;
1213
use std::ffi::OsString;
13-
use std::collections::HashMap;
14+
use std::path::{Path, PathBuf};
1415
use std::sync::{Arc, Mutex, MutexGuard};
1516

1617
// Ensures we don't race on the env vars. This is only also important in tests,
@@ -23,19 +24,26 @@ lazy_static! {
2324
/// Requires supplying an external lock guard to guarantee env var consistency across multiple threads.
2425
pub struct Environment<'a> {
2526
old_vars: HashMap<String, Option<OsString>>,
27+
old_cwd: PathBuf,
2628
_guard: MutexGuard<'a, ()>,
2729
}
2830

2931
impl<'a> Environment<'a> {
3032
pub fn push_with_lock(
3133
envs: &HashMap<String, Option<OsString>>,
34+
cwd: Option<&Path>,
3235
lock: MutexGuard<'a, ()>,
3336
) -> Environment<'a> {
3437
let mut result = Environment {
3538
old_vars: HashMap::new(),
39+
old_cwd: env::current_dir().expect("failed to read cwd"),
3640
_guard: lock,
3741
};
3842

43+
if let Some(cwd) = cwd {
44+
env::set_current_dir(cwd).expect("failed to change cwd");
45+
}
46+
3947
for (k, v) in envs {
4048
result.push_var(k, v);
4149
}
@@ -49,10 +57,15 @@ impl<'a> Environment<'a> {
4957
None => env::remove_var(key),
5058
}
5159
}
60+
61+
pub fn get_old_cwd(&self) -> &Path {
62+
&self.old_cwd
63+
}
5264
}
5365

5466
impl<'a> Drop for Environment<'a> {
5567
fn drop(&mut self) {
68+
drop(env::set_current_dir(&self.old_cwd));
5669
for (k, v) in &self.old_vars {
5770
match *v {
5871
Some(ref v) => env::set_var(k, v),

0 commit comments

Comments
 (0)