diff --git a/Cargo.lock b/Cargo.lock index def4ed45e0..7de784c1cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1364,6 +1364,7 @@ dependencies = [ "ra_syntax", "ra_text_edit", "ra_tt", + "ra_toolchain", "ra_vfs", "rand", "relative-path", diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 65b487db3b..2e49448cc6 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -48,6 +48,7 @@ hir = { path = "../ra_hir", package = "ra_hir" } hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } ra_proc_macro_srv = { path = "../ra_proc_macro_srv" } +ra_toolchain = { path = "../ra_toolchain" } [target.'cfg(windows)'.dependencies] winapi = "0.3.8" diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 1f910ff82b..1b5b3325c0 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -40,6 +40,7 @@ use crate::{ world::WorldSnapshot, LspError, Result, }; +use anyhow::Context; pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result { let _p = profile("handle_analyzer_status"); @@ -982,10 +983,15 @@ fn to_lsp_runnable( target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) } }; + let cargo_path = ra_toolchain::cargo() + .to_str() + .context("Path to cargo executable contains invalid UTF8 characters")? + .to_owned(); + Ok(lsp_ext::Runnable { range: to_proto::range(&line_index, runnable.range), label, - bin: "cargo".to_string(), + bin: cargo_path, args, extra_args, env: { diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index a55b2f860f..46cd3d7778 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -126,8 +126,8 @@ export class Cargo { } } -// Mirrors `ra_env::get_path_for_executable` implementation -function getCargoPathOrFail(): string { +// Mirrors `ra_toolchain::cargo()` implementation +export function getCargoPathOrFail(): string { const envVar = process.env.CARGO; const executableName = "cargo"; diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts index 1366c76d6b..c22d693623 100644 --- a/editors/code/src/tasks.ts +++ b/editors/code/src/tasks.ts @@ -1,4 +1,5 @@ import * as vscode from 'vscode'; +import { getCargoPathOrFail } from "./cargo"; // This ends up as the `type` key in tasks.json. RLS also uses `cargo` and // our configuration should be compatible with it so use the same key. @@ -24,6 +25,8 @@ class CargoTaskProvider implements vscode.TaskProvider { // set of tasks that always exist. These tasks cannot be removed in // tasks.json - only tweaked. + const cargoPath = getCargoPathOrFail(); + return [ { command: 'build', group: vscode.TaskGroup.Build }, { command: 'check', group: vscode.TaskGroup.Build }, @@ -46,7 +49,7 @@ class CargoTaskProvider implements vscode.TaskProvider { `cargo ${command}`, 'rust', // What to do when this command is executed. - new vscode.ShellExecution('cargo', [command]), + new vscode.ShellExecution(cargoPath, [command]), // Problem matchers. ['$rustc'], ); @@ -80,4 +83,4 @@ class CargoTaskProvider implements vscode.TaskProvider { export function activateTaskProvider(target: vscode.WorkspaceFolder): vscode.Disposable { const provider = new CargoTaskProvider(target); return vscode.tasks.registerTaskProvider(TASK_TYPE, provider); -} \ No newline at end of file +}