Skip to content

Commit f647edc

Browse files
bors[bot]matklad
andauthored
Merge #5884
5884: Add sysroot shortcut to rust-project.json r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 91bedef + 189521a commit f647edc

File tree

3 files changed

+70
-22
lines changed

3 files changed

+70
-22
lines changed

crates/project_model/src/lib.rs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,18 @@ pub enum ProjectWorkspace {
3939
impl fmt::Debug for ProjectWorkspace {
4040
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4141
match self {
42-
ProjectWorkspace::Cargo { cargo, .. } => {
43-
f.debug_struct("Cargo").field("n_packages", &cargo.packages().len()).finish()
44-
}
42+
ProjectWorkspace::Cargo { cargo, sysroot } => f
43+
.debug_struct("Cargo")
44+
.field("n_packages", &cargo.packages().len())
45+
.field("n_sysroot_crates", &sysroot.crates().len())
46+
.finish(),
4547
ProjectWorkspace::Json { project } => {
46-
f.debug_struct("Json").field("n_crates", &project.n_crates()).finish()
48+
let mut debug_struct = f.debug_struct("Json");
49+
debug_struct.field("n_crates", &project.n_crates());
50+
if let Some(sysroot) = &project.sysroot {
51+
debug_struct.field("n_sysroot_crates", &sysroot.crates().len());
52+
}
53+
debug_struct.finish()
4754
}
4855
}
4956
}
@@ -210,6 +217,13 @@ impl ProjectWorkspace {
210217
})
211218
.collect::<FxHashSet<_>>()
212219
.into_iter()
220+
.chain(project.sysroot.as_ref().into_iter().flat_map(|sysroot| {
221+
sysroot.crates().map(move |krate| PackageRoot {
222+
is_member: false,
223+
include: vec![sysroot[krate].root_dir().to_path_buf()],
224+
exclude: Vec::new(),
225+
})
226+
}))
213227
.collect::<Vec<_>>(),
214228
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
215229
.packages()
@@ -272,6 +286,11 @@ impl ProjectWorkspace {
272286
let mut crate_graph = CrateGraph::default();
273287
match self {
274288
ProjectWorkspace::Json { project } => {
289+
let sysroot_dps = project
290+
.sysroot
291+
.as_ref()
292+
.map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load));
293+
275294
let mut cfg_cache: FxHashMap<Option<&str>, Vec<CfgFlag>> = FxHashMap::default();
276295
let crates: FxHashMap<_, _> = project
277296
.crates()
@@ -309,25 +328,33 @@ impl ProjectWorkspace {
309328
.collect();
310329

311330
for (from, krate) in project.crates() {
312-
for dep in &krate.deps {
313-
let to_crate_id = dep.crate_id;
314-
if let (Some(&from), Some(&to)) =
315-
(crates.get(&from), crates.get(&to_crate_id))
316-
{
317-
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
318-
log::error!("cyclic dependency {:?} -> {:?}", from, to_crate_id);
331+
if let Some(&from) = crates.get(&from) {
332+
if let Some((public_deps, _proc_macro)) = &sysroot_dps {
333+
for (name, to) in public_deps.iter() {
334+
if let Err(_) = crate_graph.add_dep(from, name.clone(), *to) {
335+
log::error!("cyclic dependency on {} for {:?}", name, from)
336+
}
337+
}
338+
}
339+
340+
for dep in &krate.deps {
341+
let to_crate_id = dep.crate_id;
342+
if let Some(&to) = crates.get(&to_crate_id) {
343+
if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) {
344+
log::error!("cyclic dependency {:?} -> {:?}", from, to);
345+
}
319346
}
320347
}
321348
}
322349
}
323350
}
324351
ProjectWorkspace::Cargo { cargo, sysroot } => {
352+
let (public_deps, libproc_macro) =
353+
sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load);
354+
325355
let mut cfg_options = CfgOptions::default();
326356
cfg_options.extend(get_rustc_cfg_options(target));
327357

328-
let (public_deps, libproc_macro) =
329-
sysroot_to_crate_graph(&mut crate_graph, sysroot, &cfg_options, load);
330-
331358
let mut pkg_to_lib_crate = FxHashMap::default();
332359
let mut pkg_crates = FxHashMap::default();
333360

@@ -410,7 +437,11 @@ impl ProjectWorkspace {
410437
}
411438
for (name, krate) in public_deps.iter() {
412439
if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) {
413-
log::error!("cyclic dependency on core for {}", &cargo[pkg].name)
440+
log::error!(
441+
"cyclic dependency on {} for {}",
442+
name,
443+
&cargo[pkg].name
444+
)
414445
}
415446
}
416447
}
@@ -485,9 +516,11 @@ fn utf8_stdout(mut cmd: Command) -> Result<String> {
485516
fn sysroot_to_crate_graph(
486517
crate_graph: &mut CrateGraph,
487518
sysroot: &Sysroot,
488-
cfg_options: &CfgOptions,
519+
target: Option<&str>,
489520
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
490521
) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) {
522+
let mut cfg_options = CfgOptions::default();
523+
cfg_options.extend(get_rustc_cfg_options(target));
491524
let sysroot_crates: FxHashMap<_, _> = sysroot
492525
.crates()
493526
.filter_map(|krate| {

crates/project_model/src/project_json.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ use paths::{AbsPath, AbsPathBuf};
77
use rustc_hash::FxHashMap;
88
use serde::{de, Deserialize};
99

10-
use crate::cfg_flag::CfgFlag;
10+
use crate::{cfg_flag::CfgFlag, Sysroot};
1111

1212
/// Roots and crates that compose this Rust project.
1313
#[derive(Clone, Debug, Eq, PartialEq)]
1414
pub struct ProjectJson {
15+
pub(crate) sysroot: Option<Sysroot>,
1516
crates: Vec<Crate>,
1617
}
1718

@@ -34,6 +35,7 @@ pub struct Crate {
3435
impl ProjectJson {
3536
pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson {
3637
ProjectJson {
38+
sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)),
3739
crates: data
3840
.crates
3941
.into_iter()
@@ -43,11 +45,13 @@ impl ProjectJson {
4345
&& !crate_data.root_module.starts_with("..")
4446
|| crate_data.root_module.starts_with(base)
4547
});
46-
let root_module = base.join(crate_data.root_module);
48+
let root_module = base.join(crate_data.root_module).normalize();
4749
let (include, exclude) = match crate_data.source {
4850
Some(src) => {
4951
let absolutize = |dirs: Vec<PathBuf>| {
50-
dirs.into_iter().map(|it| base.join(it)).collect::<Vec<_>>()
52+
dirs.into_iter()
53+
.map(|it| base.join(it).normalize())
54+
.collect::<Vec<_>>()
5155
};
5256
(absolutize(src.include_dirs), absolutize(src.exclude_dirs))
5357
}
@@ -89,6 +93,7 @@ impl ProjectJson {
8993

9094
#[derive(Deserialize)]
9195
pub struct ProjectJsonData {
96+
sysroot_src: Option<PathBuf>,
9297
crates: Vec<CrateData>,
9398
}
9499

docs/user/manual.adoc

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,19 @@ However, if you use some other build system, you'll have to describe the structu
273273
[source,TypeScript]
274274
----
275275
interface JsonProject {
276-
/// The set of crates comprising the current project.
277-
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
278-
crates: Crate[];
276+
/// Path to the directory with *source code* of sysroot crates.
277+
///
278+
/// It should point to the directory where std, core, and friends can be found:
279+
/// https://github.com/rust-lang/rust/tree/master/library.
280+
///
281+
/// If provided, rust-analyzer automatically adds dependencies on sysroot
282+
/// crates. Conversely, if you omit this path, you can specify sysroot
283+
/// dependencies yourself and, for example, have several different "sysroots" in
284+
/// one graph of crates.
285+
sysroot_src?: string;
286+
/// The set of crates comprising the current project.
287+
/// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
288+
crates: Crate[];
279289
}
280290
281291
interface Crate {

0 commit comments

Comments
 (0)