mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 11:04:03 +00:00
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 <vit@conrlab.com>
This commit is contained in:
commit
fb45d2adec
@ -353,8 +353,9 @@
|
|||||||
"Use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)"
|
"Use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"rust-analyzer.debug.sourceFileMap": {
|
"rust-analyzer.debug.sourceFileMap": {
|
||||||
"type": "object",
|
"type": ["object", "string"],
|
||||||
|
"const": "auto",
|
||||||
"description": "Optional source file mappings passed to the debug engine.",
|
"description": "Optional source file mappings passed to the debug engine.",
|
||||||
"default": {
|
"default": {
|
||||||
"/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust"
|
"/rustc/<id>": "${env:USERPROFILE}/.rustup/toolchains/<toolchain-id>/lib/rustlib/src/rust"
|
||||||
|
@ -135,8 +135,12 @@ export class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get debug() {
|
get debug() {
|
||||||
// "/rustc/<id>" used by suggestions only.
|
let sourceFileMap = this.get<Record<string, string> | "auto">("debug.sourceFileMap");
|
||||||
const { ["/rustc/<id>"]: _, ...sourceFileMap } = this.get<Record<string, string>>("debug.sourceFileMap");
|
if (sourceFileMap !== "auto") {
|
||||||
|
// "/rustc/<id>" used by suggestions only.
|
||||||
|
const { ["/rustc/<id>"]: _, ...trimmed } = this.get<Record<string, string>>("debug.sourceFileMap");
|
||||||
|
sourceFileMap = trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
engine: this.get<string>("debug.engine"),
|
engine: this.get<string>("debug.engine"),
|
||||||
|
@ -3,7 +3,7 @@ import * as vscode from 'vscode';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as ra from './lsp_ext';
|
import * as ra from './lsp_ext';
|
||||||
|
|
||||||
import { Cargo } from './toolchain';
|
import { Cargo, getRustcId, getSysroot } from './toolchain';
|
||||||
import { Ctx } from "./ctx";
|
import { Ctx } from "./ctx";
|
||||||
import { prepareEnv } from "./run";
|
import { prepareEnv } from "./run";
|
||||||
|
|
||||||
@ -104,7 +104,17 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v
|
|||||||
|
|
||||||
const executable = await getDebugExecutable(runnable);
|
const executable = await getDebugExecutable(runnable);
|
||||||
const env = prepareEnv(runnable, ctx.config.runnableEnv);
|
const env = prepareEnv(runnable, ctx.config.runnableEnv);
|
||||||
const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), env, debugOptions.sourceFileMap);
|
let sourceFileMap = debugOptions.sourceFileMap;
|
||||||
|
if (sourceFileMap === "auto") {
|
||||||
|
// let's try to use the default toolchain
|
||||||
|
const commitHash = await getRustcId(wsFolder);
|
||||||
|
const sysroot = await getSysroot(wsFolder);
|
||||||
|
const rustlib = path.normalize(sysroot + "/lib/rustlib/src/rust");
|
||||||
|
sourceFileMap = {};
|
||||||
|
sourceFileMap[`/rustc/${commitHash}/`] = rustlib;
|
||||||
|
}
|
||||||
|
|
||||||
|
const debugConfig = knownEngines[debugEngine.id](runnable, simplifyPath(executable), env, sourceFileMap);
|
||||||
if (debugConfig.type in debugOptions.engineSettings) {
|
if (debugConfig.type in debugOptions.engineSettings) {
|
||||||
const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
|
const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
|
||||||
for (var key in settingsMap) {
|
for (var key in settingsMap) {
|
||||||
|
@ -4,7 +4,7 @@ import * as path from 'path';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as readline from 'readline';
|
import * as readline from 'readline';
|
||||||
import { OutputChannel } from 'vscode';
|
import { OutputChannel } from 'vscode';
|
||||||
import { log, memoize } from './util';
|
import { execute, log, memoize } from './util';
|
||||||
|
|
||||||
interface CompilationArtifact {
|
interface CompilationArtifact {
|
||||||
fileName: string;
|
fileName: string;
|
||||||
@ -121,6 +121,24 @@ export class Cargo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
|
||||||
|
export function getSysroot(dir: string): Promise<string> {
|
||||||
|
const rustcPath = getPathForExecutable("rustc");
|
||||||
|
|
||||||
|
// do not memoize the result because the toolchain may change between runs
|
||||||
|
return execute(`${rustcPath} --print sysroot`, { cwd: dir });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRustcId(dir: string): Promise<string> {
|
||||||
|
const rustcPath = getPathForExecutable("rustc");
|
||||||
|
|
||||||
|
// do not memoize the result because the toolchain may change between runs
|
||||||
|
const data = await execute(`${rustcPath} -V -v`, { cwd: dir });
|
||||||
|
const rx = /commit-hash:\s(.*)$/m.compile();
|
||||||
|
|
||||||
|
return rx.exec(data)![1];
|
||||||
|
}
|
||||||
|
|
||||||
/** Mirrors `toolchain::cargo()` implementation */
|
/** Mirrors `toolchain::cargo()` implementation */
|
||||||
export function cargoPath(): string {
|
export function cargoPath(): string {
|
||||||
return getPathForExecutable("cargo");
|
return getPathForExecutable("cargo");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as lc from "vscode-languageclient/node";
|
import * as lc from "vscode-languageclient/node";
|
||||||
import * as vscode from "vscode";
|
import * as vscode from "vscode";
|
||||||
import { strict as nativeAssert } from "assert";
|
import { strict as nativeAssert } from "assert";
|
||||||
import { spawnSync } from "child_process";
|
import { exec, ExecOptions, spawnSync } from "child_process";
|
||||||
import { inspect } from "util";
|
import { inspect } from "util";
|
||||||
|
|
||||||
export function assert(condition: boolean, explanation: string): asserts condition {
|
export function assert(condition: boolean, explanation: string): asserts condition {
|
||||||
@ -141,3 +141,22 @@ export function memoize<Ret, TThis, Param extends string>(func: (this: TThis, ar
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Awaitable wrapper around `child_process.exec` */
|
||||||
|
export function execute(command: string, options: ExecOptions): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(command, options, (err, stdout, stderr) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stderr) {
|
||||||
|
reject(new Error(stderr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(stdout.trimEnd());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user