Skip to content

Commit b586947

Browse files
committed
rust-project: populate sysroot_src
According to https://rust-analyzer.github.io/book/non_cargo_based_projects.html, rust-analyzer should compute `sysroot_src` from `sysroot` if it is absent. According to my testing, this is not the case, and rust-analyzer is broken if `sysroot_src` is not populated. To fix this, we populate it from a new `--sysroot-src` flag, or the de facto standard `RUST_SRC_PATH`, which fixes the issue. Ideally, rust-analyzer should be fixed but: 1. I haven't gotten to the bottom of that bug. 2. This commit remains correct in the meantime. 3. This commit allows setups where the binary sysroot and source sysroots are different (as is the case in Nixpks, where they come from different packages).
1 parent 4214c15 commit b586947

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

integrations/rust-project/src/cli/develop.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl Develop {
6262
stdout,
6363
prefer_rustup_managed_toolchain,
6464
sysroot,
65+
sysroot_src,
6566
pretty,
6667
mode,
6768
check_cycles,
@@ -80,7 +81,21 @@ impl Develop {
8081
let sysroot = if prefer_rustup_managed_toolchain {
8182
SysrootConfig::Rustup
8283
} else if let Some(sysroot) = sysroot {
83-
SysrootConfig::Sysroot(sysroot)
84+
// sysroot_src priority:
85+
// 1. --sysroot-src flag
86+
// 2. RUST_SRC_PATH env var
87+
// 3. --sysroot flag
88+
let sysroot_src = sysroot_src
89+
.or_else(|| {
90+
std::env::var("RUST_SRC_PATH")
91+
.ok()
92+
.map(|s| PathBuf::from(&s))
93+
})
94+
.unwrap_or(sysroot.clone());
95+
SysrootConfig::Sysroot {
96+
sysroot,
97+
sysroot_src,
98+
}
8499
} else {
85100
SysrootConfig::BuckConfig
86101
};
@@ -126,13 +141,20 @@ impl Develop {
126141
let sysroot = match sysroot_mode {
127142
crate::SysrootMode::BuckConfig => SysrootConfig::BuckConfig,
128143
crate::SysrootMode::Rustc => SysrootConfig::Rustup,
129-
crate::SysrootMode::FullPath(path) => SysrootConfig::Sysroot(path),
144+
crate::SysrootMode::FullPath(path) => SysrootConfig::Sysroot {
145+
sysroot: path.clone(),
146+
sysroot_src: path,
147+
},
130148
crate::SysrootMode::Command(cmd_args) => {
131149
let cmd = cmd_args[0].clone();
132150
let args = cmd_args[1..].to_vec();
133151
let output = std::process::Command::new(cmd).args(args).output().unwrap();
134152
let path = String::from_utf8(output.stdout).unwrap();
135-
SysrootConfig::Sysroot(PathBuf::from(path.trim()))
153+
let path = PathBuf::from(path.trim());
154+
SysrootConfig::Sysroot {
155+
sysroot: path.clone(),
156+
sysroot_src: path,
157+
}
136158
}
137159
};
138160

@@ -279,9 +301,12 @@ impl Develop {
279301

280302
info!(kind = "progress", "finding std source code");
281303
let sysroot = match &sysroot {
282-
SysrootConfig::Sysroot(path) => Sysroot {
283-
sysroot: safe_canonicalize(&expand_tilde(path)?),
284-
sysroot_src: None,
304+
SysrootConfig::Sysroot {
305+
sysroot,
306+
sysroot_src,
307+
} => Sysroot {
308+
sysroot: safe_canonicalize(&expand_tilde(sysroot)?),
309+
sysroot_src: Some(safe_canonicalize(&expand_tilde(&sysroot_src)?)),
285310
sysroot_project: None,
286311
},
287312
SysrootConfig::BuckConfig => {

integrations/rust-project/src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,18 @@ enum Command {
8989
#[clap(long, conflicts_with = "sysroot")]
9090
prefer_rustup_managed_toolchain: bool,
9191

92-
/// The directory containing the Rust source code, including std.
92+
/// The directory containing the Rust standard library and the rust-analyzer proc macro
93+
/// server.
9394
/// Default value is determined based on platform.
9495
#[clap(short = 's', long)]
9596
sysroot: Option<PathBuf>,
9697

98+
/// The directory containing the Rust standard library source code.
99+
/// Defaults to the value of the `RUST_SRC_PATH` environment variable, if set, or the
100+
/// `--sysroot` flag otherwise.
101+
#[clap(long)]
102+
sysroot_src: Option<PathBuf>,
103+
97104
/// Pretty-print generated `rust-project.json` file.
98105
#[clap(short, long)]
99106
pretty: bool,

integrations/rust-project/src/sysroot.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ use crate::target::Target;
2525

2626
#[derive(Debug)]
2727
pub(crate) enum SysrootConfig {
28-
Sysroot(PathBuf),
28+
Sysroot {
29+
sysroot: PathBuf,
30+
sysroot_src: PathBuf,
31+
},
2932
BuckConfig,
3033
Rustup,
3134
}

0 commit comments

Comments
 (0)