Skip to content

Commit ae420e3

Browse files
committed
Auto merge of #17857 - ChayimFriedman2:rust-project-cfg-group, r=Veykril
feat: Allow declaring cfg groups in rust-project.json, to help sharing common cfgs Closes #17815.
2 parents 4be4617 + 2607c09 commit ae420e3

File tree

5 files changed

+619
-4
lines changed

5 files changed

+619
-4
lines changed

crates/project-model/src/project_json.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
use base_db::{CrateDisplayName, CrateName};
5353
use cfg::CfgAtom;
5454
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
55-
use rustc_hash::FxHashMap;
55+
use rustc_hash::{FxHashMap, FxHashSet};
5656
use serde::{de, Deserialize, Serialize};
5757
use span::Edition;
5858

@@ -122,6 +122,25 @@ impl ProjectJson {
122122
None => None,
123123
};
124124

125+
let cfg = crate_data
126+
.cfg_groups
127+
.iter()
128+
.flat_map(|cfg_extend| {
129+
let cfg_group = data.cfg_groups.get(cfg_extend);
130+
match cfg_group {
131+
Some(cfg_group) => cfg_group.0.iter().cloned(),
132+
None => {
133+
tracing::error!(
134+
"Unknown cfg group `{cfg_extend}` in crate `{}`",
135+
crate_data.display_name.as_deref().unwrap_or("<unknown>"),
136+
);
137+
[].iter().cloned()
138+
}
139+
}
140+
})
141+
.chain(crate_data.cfg.0)
142+
.collect();
143+
125144
Crate {
126145
display_name: crate_data
127146
.display_name
@@ -131,7 +150,7 @@ impl ProjectJson {
131150
edition: crate_data.edition.into(),
132151
version: crate_data.version.as_ref().map(ToString::to_string),
133152
deps: crate_data.deps,
134-
cfg: crate_data.cfg,
153+
cfg,
135154
target: crate_data.target,
136155
env: crate_data.env,
137156
proc_macro_dylib_path: crate_data
@@ -306,11 +325,17 @@ pub enum RunnableKind {
306325
pub struct ProjectJsonData {
307326
sysroot: Option<Utf8PathBuf>,
308327
sysroot_src: Option<Utf8PathBuf>,
328+
#[serde(default)]
329+
cfg_groups: FxHashMap<String, CfgList>,
309330
crates: Vec<CrateData>,
310331
#[serde(default)]
311332
runnables: Vec<RunnableData>,
312333
}
313334

335+
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)]
336+
#[serde(transparent)]
337+
struct CfgList(#[serde(with = "cfg_")] Vec<CfgAtom>);
338+
314339
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
315340
struct CrateData {
316341
display_name: Option<String>,
@@ -320,8 +345,9 @@ struct CrateData {
320345
version: Option<semver::Version>,
321346
deps: Vec<Dep>,
322347
#[serde(default)]
323-
#[serde(with = "cfg_")]
324-
cfg: Vec<CfgAtom>,
348+
cfg_groups: FxHashSet<String>,
349+
#[serde(default)]
350+
cfg: CfgList,
325351
target: Option<String>,
326352
#[serde(default)]
327353
env: FxHashMap<String, String>,

crates/project-model/src/tests.rs

+6
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ fn rust_project_hello_world_project_model() {
233233
);
234234
}
235235

236+
#[test]
237+
fn rust_project_cfg_groups() {
238+
let (crate_graph, _proc_macros) = load_rust_project("cfg-groups.json");
239+
check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]);
240+
}
241+
236242
#[test]
237243
fn rust_project_is_proc_macro_has_proc_macro_dep() {
238244
let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"sysroot_src": null,
3+
"cfg_groups": {
4+
"group1": ["group1_cfg=\"some_config\"", "group1_other_cfg=\"other_config\""],
5+
"group2": ["group2_cfg=\"yet_another_config\""]
6+
},
7+
"crates": [
8+
{
9+
"display_name": "hello_world",
10+
"root_module": "$ROOT$src/lib.rs",
11+
"edition": "2018",
12+
"cfg_groups": ["group1", "group2"],
13+
"deps": [],
14+
"is_workspace_member": true
15+
},
16+
{
17+
"display_name": "other_crate",
18+
"root_module": "$ROOT$src/lib.rs",
19+
"edition": "2018",
20+
"cfg_groups": ["group2"],
21+
"cfg": ["group2_cfg=\"fourth_config\"", "unrelated_cfg"],
22+
"deps": [],
23+
"is_workspace_member": true
24+
}
25+
]
26+
}

0 commit comments

Comments
 (0)