Skip to content

Commit de8dbaa

Browse files
daricheyfacebook-github-bot
authored andcommitted
rust-project: Include buckified sysroot in project
Summary: rust-analyzer wants to drop support for their "stitched sysroot" (where it will assume the structure of the sysroot) in favor of relying on the build tool to tell it the sysroot layout. Since we have a buckified sysroot, that can be buck, and we can include a nested JsonProject for the sysroot. Corresponding rust-analyzer change: rust-lang/rust-analyzer#19096 Reviewed By: davidbarsky Differential Revision: D69328620 fbshipit-source-id: ee0b461b2e144bfefd30970d6f6ce35ae89e8ee1
1 parent d436c7c commit de8dbaa

File tree

5 files changed

+77
-27
lines changed

5 files changed

+77
-27
lines changed

integrations/rust-project/src/buck.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ pub(crate) fn to_json_project(
187187
}
188188

189189
let jp = JsonProject {
190-
sysroot,
190+
sysroot: Box::new(sysroot),
191191
crates,
192192
runnables: vec![
193193
Runnable {
@@ -504,10 +504,7 @@ impl Buck {
504504
sysroot_src_path: PathBuf,
505505
}
506506
let cfg: BuckConfig = deserialize_output(child.wait_with_output(), &command)?;
507-
// the `library` path component needs to be appended to the `sysroot_src_path`
508-
// so that rust-analyzer will be able to find standard library sources.
509-
let cfg = cfg.sysroot_src_path.join("library");
510-
Ok(cfg)
507+
Ok(cfg.sysroot_src_path)
511508
}
512509

513510
/// Determines the owning target(s) of the saved file and builds them.

integrations/rust-project/src/cli.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub(crate) enum Input {
2121
use std::path::PathBuf;
2222

2323
pub(crate) use check::Check;
24+
pub(crate) use develop::develop_with_sysroot;
2425
pub(crate) use develop::Develop;
2526
pub(crate) use new::New;
2627
pub(crate) use new::ProjectKind;

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

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use super::Input;
2121
use crate::buck;
2222
use crate::buck::select_mode;
2323
use crate::buck::to_json_project;
24+
use crate::buck::Buck;
2425
use crate::json_project::JsonProject;
2526
use crate::json_project::Sysroot;
2627
use crate::path::safe_canonicalize;
@@ -232,36 +233,31 @@ impl Develop {
232233
..
233234
} = self;
234235

235-
let project_root = buck.resolve_project_root()?;
236-
237-
info!("building generated code");
238-
let exclude_workspaces =
239-
std::env::var("RUST_PROJECT_EXCLUDE_WORKSPACES").is_ok_and(|it| it != "0");
240-
let expanded_and_resolved = buck.expand_and_resolve(&targets, exclude_workspaces)?;
241-
242-
info!("resolving aliased libraries");
243-
let aliased_libraries =
244-
buck.query_aliased_libraries(&expanded_and_resolved.expanded_targets)?;
245-
246236
info!("fetching sysroot");
247237
let sysroot = match &sysroot {
248238
SysrootConfig::Sysroot(path) => Sysroot {
249239
sysroot: safe_canonicalize(&expand_tilde(path)?),
250240
sysroot_src: None,
241+
sysroot_project: None,
251242
},
252-
SysrootConfig::BuckConfig => resolve_buckconfig_sysroot(&buck, &project_root)?,
243+
SysrootConfig::BuckConfig => {
244+
let project_root = buck.resolve_project_root()?;
245+
resolve_buckconfig_sysroot(&buck, &project_root)?
246+
}
253247
SysrootConfig::Rustup => resolve_rustup_sysroot()?,
254248
};
255-
info!("converting buck info to rust-project.json");
256-
let rust_project = to_json_project(
249+
250+
let exclude_workspaces =
251+
std::env::var("RUST_PROJECT_EXCLUDE_WORKSPACES").is_ok_and(|it| it != "0");
252+
253+
develop_with_sysroot(
254+
buck,
255+
targets,
257256
sysroot,
258-
expanded_and_resolved,
259-
aliased_libraries,
257+
exclude_workspaces,
260258
*check_cycles,
261259
*include_all_buildfiles,
262-
)?;
263-
264-
Ok(rust_project)
260+
)
265261
}
266262

267263
/// For every Rust file, return the relevant buck targets that should be used to configure rust-analyzer.
@@ -292,3 +288,30 @@ fn expand_tilde(path: &Path) -> Result<PathBuf, anyhow::Error> {
292288
Ok(path.to_path_buf())
293289
}
294290
}
291+
292+
pub(crate) fn develop_with_sysroot(
293+
buck: &Buck,
294+
targets: Vec<Target>,
295+
sysroot: Sysroot,
296+
exclude_workspaces: bool,
297+
check_cycles: bool,
298+
include_all_buildfiles: bool,
299+
) -> Result<JsonProject, anyhow::Error> {
300+
info!("building generated code");
301+
let expanded_and_resolved = buck.expand_and_resolve(&targets, exclude_workspaces)?;
302+
303+
info!("resolving aliased libraries");
304+
let aliased_libraries =
305+
buck.query_aliased_libraries(&expanded_and_resolved.expanded_targets)?;
306+
307+
info!("converting buck info to rust-project.json");
308+
let rust_project = to_json_project(
309+
sysroot,
310+
expanded_and_resolved,
311+
aliased_libraries,
312+
check_cycles,
313+
include_all_buildfiles,
314+
)?;
315+
316+
Ok(rust_project)
317+
}

integrations/rust-project/src/json_project.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::target::Target;
2727
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
2828
pub(crate) struct JsonProject {
2929
#[serde(flatten)]
30-
pub(crate) sysroot: Sysroot,
30+
pub(crate) sysroot: Box<Sysroot>,
3131

3232
/// The set of crates comprising the project.
3333
///
@@ -216,7 +216,7 @@ pub(crate) struct Dep {
216216

217217
/// Sysroot paths. These are documented in the rust-analyzer manual:
218218
///
219-
/// <https://rust-analyzer.github.io/manual.html#non-cargo-based-projects>
219+
/// <https://rust-analyzer.github.io/book/non_cargo_based_projects.html>
220220
///
221221
/// rust-analyzer treats both paths as optional, but we always provide sysroot.
222222
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
@@ -241,4 +241,11 @@ pub(crate) struct Sysroot {
241241
/// are packaged seperately from binaries such as `rust-analyzer-proc-macro-srv`.
242242
#[serde(skip_serializing_if = "Option::is_none")]
243243
pub(crate) sysroot_src: Option<PathBuf>,
244+
/// A nested rust-project for the sysroot itself. If not provided, rust-analyzer
245+
/// will attempt to compute the sysroot layout with Cargo.
246+
///
247+
/// Inside Meta, we have a Buck-ified rust toolchain and we can provide the
248+
/// sysroot layout directly with Buck.
249+
#[serde(skip_serializing_if = "Option::is_none")]
250+
pub(crate) sysroot_project: Option<JsonProject>,
244251
}

integrations/rust-project/src/sysroot.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ use tracing::instrument;
1818
use crate::buck::truncate_line_ending;
1919
use crate::buck::utf8_output;
2020
use crate::buck::Buck;
21+
use crate::cli::develop_with_sysroot;
2122
use crate::json_project::Sysroot;
23+
use crate::target::Target;
2224

2325
#[derive(Debug)]
2426
pub(crate) enum SysrootConfig {
@@ -40,7 +42,6 @@ pub(crate) fn resolve_buckconfig_sysroot(
4042
buck: &Buck,
4143
project_root: &Path,
4244
) -> Result<Sysroot, anyhow::Error> {
43-
let sysroot_src = project_root.join(buck.resolve_sysroot_src()?);
4445
let sysroot: PathBuf = {
4546
// TODO(diliopoulos): remove hardcoded path to toolchain sysroot and replace with something
4647
// derived from buck, e.g.
@@ -66,9 +67,29 @@ pub(crate) fn resolve_buckconfig_sysroot(
6667
sysroot.into()
6768
};
6869

70+
let sysroot_src = buck.resolve_sysroot_src()?;
71+
let sysroot_targets = Target::new(format!("fbsource//{}:", sysroot_src.to_string_lossy()));
72+
// the `library` path component needs to be appended to the `sysroot_src_path`
73+
// so that rust-analyzer will be able to find standard library sources.
74+
let sysroot_src = project_root.join(sysroot_src).join("library");
75+
76+
let sysroot_project = develop_with_sysroot(
77+
buck,
78+
vec![sysroot_targets],
79+
Sysroot {
80+
sysroot: sysroot.clone(),
81+
sysroot_src: Some(sysroot_src.clone()),
82+
sysroot_project: None,
83+
},
84+
true,
85+
false,
86+
false,
87+
)?;
88+
6989
Ok(Sysroot {
7090
sysroot,
7191
sysroot_src: Some(sysroot_src),
92+
sysroot_project: Some(sysroot_project),
7293
})
7394
}
7495

@@ -93,6 +114,7 @@ pub(crate) fn resolve_rustup_sysroot() -> Result<Sysroot, anyhow::Error> {
93114
let sysroot = Sysroot {
94115
sysroot,
95116
sysroot_src: Some(sysroot_src),
117+
sysroot_project: None, // rustup sysroot is not buckified
96118
};
97119
Ok(sysroot)
98120
}

0 commit comments

Comments
 (0)