aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-27 21:41:35 +0100
committerGitHub <[email protected]>2021-04-27 21:41:35 +0100
commitfb45d2adeccfc6732b702cd8fa2911b385bc15b7 (patch)
tree41ab22e69528ccb346bc01b913f9251a24925960 /editors
parente2b87735cc4b54ca530e7a99070da585d480b1c3 (diff)
parent1b4197cb3520e4a71f118aac61a83bab1a6f5931 (diff)
Merge #8624
8624: Automatically detect rust library source file map r=vsrs a=vsrs This PR adds a new possible `rust-analyzer.debug.sourceFileMap` value: ```json { "rust-analyzer.debug.sourceFileMap": "auto" } ``` I did not make it the default because it uses two shell calls (`rustc --print sysroot` and `rustc -V -v`). First one can be slow (https://github.com/rust-lang/rustup/issues/783) Fixes #8619 Co-authored-by: vsrs <[email protected]>
Diffstat (limited to 'editors')
-rw-r--r--editors/code/package.json5
-rw-r--r--editors/code/src/config.ts8
-rw-r--r--editors/code/src/debug.ts14
-rw-r--r--editors/code/src/toolchain.ts20
-rw-r--r--editors/code/src/util.ts21
5 files changed, 60 insertions, 8 deletions
diff --git a/editors/code/package.json b/editors/code/package.json
index 97d92e43c..35b50e669 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -353,8 +353,9 @@
353 "Use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)" 353 "Use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)"
354 ] 354 ]
355 }, 355 },
356 "rust-analyzer.debug.sourceFileMap": { 356 "rust-analyzer.debug.sourceFileMap": {
357 "type": "object", 357 "type": ["object", "string"],
358 "const": "auto",
358 "description": "Optional source file mappings passed to the debug engine.", 359 "description": "Optional source file mappings passed to the debug engine.",
359 "default": { 360 "default": {
360 "/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust" 361 "/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust"
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index 03f7d7cc3..e858f80bc 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -135,8 +135,12 @@ export class Config {
135 } 135 }
136 136
137 get debug() { 137 get debug() {
138 // "/rustc/<id>" used by suggestions only. 138 let sourceFileMap = this.get<Record<string, string> | "auto">("debug.sourceFileMap");
139 const { ["/rustc/<id>"]: _, ...sourceFileMap } = this.get<Record<string, string>>("debug.sourceFileMap"); 139 if (sourceFileMap !== "auto") {
140 // "/rustc/<id>" used by suggestions only.
141 const { ["/rustc/<id>"]: _, ...trimmed } = this.get<Record<string, string>>("debug.sourceFileMap");
142 sourceFileMap = trimmed;
143 }
140 144
141 return { 145 return {
142 engine: this.get<string>("debug.engine"), 146 engine: this.get<string>("debug.engine"),
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index 3889a2773..830980f96 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -3,7 +3,7 @@ import * as vscode from 'vscode';
3import * as path from 'path'; 3import * as path from 'path';
4import * as ra from './lsp_ext'; 4import * as ra from './lsp_ext';
5 5
6import { Cargo } from './toolchain'; 6import { Cargo, getRustcId, getSysroot } from './toolchain';
7import { Ctx } from "./ctx"; 7import { Ctx } from "./ctx";
8import { prepareEnv } from "./run"; 8import { prepareEnv } from "./run";
9 9
@@ -104,7 +104,17 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
104 104
105 const executable = await getDebugExecutable(runnable); 105 const executable = await getDebugExecutable(runnable);
106 const env = prepareEnv(runnable, ctx.config.runnableEnv); 106 const env = prepareEnv(runnable, ctx.config.runnableEnv);
107 const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), env, debugOptions.sourceFileMap); 107 let sourceFileMap = debugOptions.sourceFileMap;
108 if (sourceFileMap === "auto") {
109 // let's try to use the default toolchain
110 const commitHash = await getRustcId(wsFolder);
111 const sysroot = await getSysroot(wsFolder);
112 const rustlib = path.normalize(sysroot + "/lib/rustlib/src/rust");
113 sourceFileMap = {};
114 sourceFileMap[`/rustc/${commitHash}/`] = rustlib;
115 }
116
117 const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), env, sourceFileMap);
108 if (debugConfig.type in debugOptions.engineSettings) { 118 if (debugConfig.type in debugOptions.engineSettings) {
109 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type]; 119 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
110 for (var key in settingsMap) { 120 for (var key in settingsMap) {
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
index a5dc3cf0c..68826c478 100644
--- a/editors/code/src/toolchain.ts
+++ b/editors/code/src/toolchain.ts
@@ -4,7 +4,7 @@ import * as path from 'path';
4import * as fs from 'fs'; 4import * as fs from 'fs';
5import * as readline from 'readline'; 5import * as readline from 'readline';
6import { OutputChannel } from 'vscode'; 6import { OutputChannel } from 'vscode';
7import { log, memoize } from './util'; 7import { execute, log, memoize } from './util';
8 8
9interface CompilationArtifact { 9interface CompilationArtifact {
10 fileName: string; 10 fileName: string;
@@ -121,6 +121,24 @@ export class Cargo {
121 } 121 }
122} 122}
123 123
124/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
125export function getSysroot(dir: string): Promise<string> {
126 const rustcPath = getPathForExecutable("rustc");
127
128 // do not memoize the result because the toolchain may change between runs
129 return execute(`${rustcPath} --print sysroot`, { cwd: dir });
130}
131
132export async function getRustcId(dir: string): Promise<string> {
133 const rustcPath = getPathForExecutable("rustc");
134
135 // do not memoize the result because the toolchain may change between runs
136 const data = await execute(`${rustcPath} -V -v`, { cwd: dir });
137 const rx = /commit-hash:\s(.*)$/m.compile();
138
139 return rx.exec(data)![1];
140}
141
124/** Mirrors `toolchain::cargo()` implementation */ 142/** Mirrors `toolchain::cargo()` implementation */
125export function cargoPath(): string { 143export function cargoPath(): string {
126 return getPathForExecutable("cargo"); 144 return getPathForExecutable("cargo");
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 53492a445..56e0e439e 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,7 +1,7 @@
1import * as lc from "vscode-languageclient/node"; 1import * as lc from "vscode-languageclient/node";
2import * as vscode from "vscode"; 2import * as vscode from "vscode";
3import { strict as nativeAssert } from "assert"; 3import { strict as nativeAssert } from "assert";
4import { spawnSync } from "child_process"; 4import { exec, ExecOptions, spawnSync } from "child_process";
5import { inspect } from "util"; 5import { inspect } from "util";
6 6
7export function assert(condition: boolean, explanation: string): asserts condition { 7export function assert(condition: boolean, explanation: string): asserts condition {
@@ -141,3 +141,22 @@ export function memoize<Ret, TThis, Param extends string>(func: (this: TThis, ar
141 return result; 141 return result;
142 }; 142 };
143} 143}
144
145/** Awaitable wrapper around `child_process.exec` */
146export function execute(command: string, options: ExecOptions): Promise<string> {
147 return new Promise((resolve, reject) => {
148 exec(command, options, (err, stdout, stderr) => {
149 if (err) {
150 reject(err);
151 return;
152 }
153
154 if (stderr) {
155 reject(new Error(stderr));
156 return;
157 }
158
159 resolve(stdout.trimEnd());
160 });
161 });
162}