Skip to content

Commit 50bdeaa

Browse files
committed
Auto merge of #17108 - Veykril:rustc-ws-hacks, r=Veykril
internal: Cleanup cfg and env handling in project-model Fixesrust-lang/rust-analyzer#16122 (comment) `miri` and `debug_assertions` are now enabled via the `cargo.cfgs` config by default, allowing them to be disabled by overwriting the config.
2 parents 05428c5 + cdb8c3a commit 50bdeaa

23 files changed

Lines changed: 504 additions & 311 deletions

‎crates/base-db/src/input.rs‎

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,30 @@ pub struct CrateData {
295295
pubis_proc_macro:bool,
296296
}
297297

298-
#[derive(Default,Debug,Clone,PartialEq,Eq)]
298+
#[derive(Default,Clone,PartialEq,Eq)]
299299
pubstructEnv{
300300
entries:FxHashMap<String,String>,
301301
}
302302

303+
impl fmt::DebugforEnv{
304+
fnfmt(&self,f:&mut fmt::Formatter<'_>) -> fmt::Result{
305+
structEnvDebug<'s>(Vec<(&'sString,&'sString)>);
306+
307+
impl fmt::DebugforEnvDebug<'_>{
308+
fnfmt(&self,f:&mut fmt::Formatter<'_>) -> fmt::Result{
309+
f.debug_map().entries(self.0.iter().copied()).finish()
310+
}
311+
}
312+
f.debug_struct("Env")
313+
.field("entries",&{
314+
letmut entries:Vec<_> = self.entries.iter().collect();
315+
entries.sort();
316+
EnvDebug(entries)
317+
})
318+
.finish()
319+
}
320+
}
321+
303322
#[derive(Debug,Clone,PartialEq,Eq,Hash)]
304323
pubstructDependency{
305324
pubcrate_id:CrateId,
@@ -331,10 +350,11 @@ impl CrateGraph {
331350
version:Option<String>,
332351
cfg_options:Arc<CfgOptions>,
333352
potential_cfg_options:Option<Arc<CfgOptions>>,
334-
env:Env,
353+
mutenv:Env,
335354
is_proc_macro:bool,
336355
origin:CrateOrigin,
337356
) -> CrateId{
357+
env.entries.shrink_to_fit();
338358
let data = CrateData{
339359
root_file_id,
340360
edition,
@@ -651,16 +671,24 @@ impl FromIterator<(String, String)> for Env {
651671
}
652672

653673
implEnv{
654-
pubfnset(&mutself,env:&str,value:String){
655-
self.entries.insert(env.to_owned(), value);
674+
pubfnset(&mutself,env:&str,value:implInto<String>){
675+
self.entries.insert(env.to_owned(), value.into());
656676
}
657677

658678
pubfnget(&self,env:&str) -> Option<String>{
659679
self.entries.get(env).cloned()
660680
}
661681

662-
pubfniter(&self) -> implIterator<Item = (&str,&str)>{
663-
self.entries.iter().map(|(k, v)| (k.as_str(), v.as_str()))
682+
pubfnextend_from_other(&mutself,other:&Env){
683+
self.entries.extend(other.entries.iter().map(|(x, y)| (x.to_owned(), y.to_owned())));
684+
}
685+
}
686+
687+
implFrom<Env>forVec<(String,String)>{
688+
fnfrom(env:Env) -> Vec<(String,String)>{
689+
letmut entries:Vec<_> = env.entries.into_iter().collect();
690+
entries.sort();
691+
entries
664692
}
665693
}
666694

‎crates/cfg/src/lib.rs‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,6 @@ impl CfgOptions {
5858
self.enabled.insert(CfgAtom::KeyValue{ key, value });
5959
}
6060

61-
pubfndifference<'a>(
62-
&'aself,
63-
other:&'aCfgOptions,
64-
) -> implIterator<Item = &'aCfgAtom> + 'a{
65-
self.enabled.difference(&other.enabled)
66-
}
67-
6861
pubfnapply_diff(&mutself,diff:CfgDiff){
6962
for atom in diff.enable{
7063
self.enabled.insert(atom);

‎crates/load-cargo/src/lib.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,7 @@ impl ProcMacroExpander for Expander {
407407
call_site:Span,
408408
mixed_site:Span,
409409
) -> Result<tt::Subtree<Span>,ProcMacroExpansionError>{
410-
let env = env.iter().map(|(k, v)| (k.to_owned(), v.to_owned())).collect();
411-
matchself.0.expand(subtree, attrs, env, def_site, call_site, mixed_site){
410+
matchself.0.expand(subtree, attrs, env.clone(), def_site, call_site, mixed_site){
412411
Ok(Ok(subtree)) => Ok(subtree),
413412
Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err.0)),
414413
Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),

‎crates/proc-macro-api/src/lib.rs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub mod msg;
1111
mod process;
1212
mod version;
1313

14+
use base_db::Env;
1415
use indexmap::IndexSet;
1516
use paths::AbsPathBuf;
1617
use rustc_hash::FxHashMap;
@@ -152,16 +153,13 @@ impl ProcMacro {
152153
&self,
153154
subtree:&tt::Subtree<Span>,
154155
attr:Option<&tt::Subtree<Span>>,
155-
env:Vec<(String,String)>,
156+
env:Env,
156157
def_site:Span,
157158
call_site:Span,
158159
mixed_site:Span,
159160
) -> Result<Result<tt::Subtree<Span>,PanicMessage>,ServerError>{
160161
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
161-
let current_dir = env
162-
.iter()
163-
.find(|(name, _)| name == "CARGO_MANIFEST_DIR")
164-
.map(|(_, value)| value.clone());
162+
let current_dir = env.get("CARGO_MANIFEST_DIR");
165163

166164
letmut span_data_table = IndexSet::default();
167165
let def_site = span_data_table.insert_full(def_site).0;
@@ -172,7 +170,7 @@ impl ProcMacro {
172170
macro_name:self.name.to_string(),
173171
attributes: attr.map(|subtree| FlatTree::new(subtree, version,&mut span_data_table)),
174172
lib:self.dylib_path.to_path_buf().into(),
175-
env,
173+
env: env.into(),
176174
current_dir,
177175
has_global_spans:ExpnGlobals{
178176
serialize: version >= HAS_GLOBAL_SPANS,

‎crates/project-model/src/build_scripts.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ use serde::Deserialize;
2323
use toolchain::Tool;
2424

2525
usecrate::{
26-
cfg_flag::CfgFlag, utf8_stdout,CargoConfig,CargoFeatures,CargoWorkspace,InvocationLocation,
26+
cfg::CfgFlag, utf8_stdout,CargoConfig,CargoFeatures,CargoWorkspace,InvocationLocation,
2727
InvocationStrategy,Package,Sysroot,TargetKind,
2828
};
2929

30+
/// Output of the build script and proc-macro building steps for a workspace.
3031
#[derive(Debug,Default,Clone,PartialEq,Eq)]
3132
pubstructWorkspaceBuildScripts{
3233
outputs:ArenaMap<Package,BuildScriptOutput>,
3334
error:Option<String>,
3435
}
3536

37+
/// Output of the build script and proc-macro building step for a concrete package.
3638
#[derive(Debug,Clone,Default,PartialEq,Eq)]
3739
pub(crate)structBuildScriptOutput{
3840
/// List of config flags defined by this package's build script.

‎crates/project-model/src/cargo_workspace.rs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,20 @@ pub struct PackageData {
135135
pubactive_features:Vec<String>,
136136
/// String representation of package id
137137
pubid:String,
138+
/// Authors as given in the `Cargo.toml`
139+
pubauthors:Vec<String>,
140+
/// Description as given in the `Cargo.toml`
141+
pubdescription:Option<String>,
142+
/// Homepage as given in the `Cargo.toml`
143+
pubhomepage:Option<String>,
144+
/// License as given in the `Cargo.toml`
145+
publicense:Option<String>,
146+
/// License file as given in the `Cargo.toml`
147+
publicense_file:Option<Utf8PathBuf>,
148+
/// Readme file as given in the `Cargo.toml`
149+
pubreadme:Option<Utf8PathBuf>,
150+
/// Rust version as given in the `Cargo.toml`
151+
pubrust_version:Option<semver::Version>,
138152
/// The contents of [package.metadata.rust-analyzer]
139153
pubmetadata:RustAnalyzerPackageMetaData,
140154
}
@@ -225,6 +239,10 @@ impl TargetKind {
225239
}
226240
TargetKind::Other
227241
}
242+
243+
pubfnis_executable(self) -> bool{
244+
matches!(self,TargetKind::Bin | TargetKind::Example)
245+
}
228246
}
229247

230248
// Deserialize helper for the cargo metadata
@@ -330,6 +348,13 @@ impl CargoWorkspace {
330348
repository,
331349
edition,
332350
metadata,
351+
authors,
352+
description,
353+
homepage,
354+
license,
355+
license_file,
356+
readme,
357+
rust_version,
333358
..
334359
} = meta_pkg;
335360
let meta = from_value::<PackageMetadata>(metadata).unwrap_or_default();
@@ -358,6 +383,13 @@ impl CargoWorkspace {
358383
is_member,
359384
edition,
360385
repository,
386+
authors,
387+
description,
388+
homepage,
389+
license,
390+
license_file,
391+
readme,
392+
rust_version,
361393
dependencies:Vec::new(),
362394
features: features.into_iter().collect(),
363395
active_features:Vec::new(),
Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
//! rustc main.rs --cfg foo --cfg 'feature="bar"'
44
use std::{fmt, str::FromStr};
55

6-
use cfg::CfgOptions;
6+
use cfg::{CfgDiff,CfgOptions};
7+
use rustc_hash::FxHashMap;
78
use serde::Serialize;
89

910
#[derive(Clone,Eq,PartialEq,Debug,Serialize)]
@@ -70,3 +71,27 @@ impl fmt::Display for CfgFlag {
7071
}
7172
}
7273
}
74+
75+
/// A set of cfg-overrides per crate.
76+
#[derive(Default,Debug,Clone,Eq,PartialEq)]
77+
pubstructCfgOverrides{
78+
/// A global set of overrides matching all crates.
79+
pubglobal:CfgDiff,
80+
/// A set of overrides matching specific crates.
81+
pubselective:FxHashMap<String,CfgDiff>,
82+
}
83+
84+
implCfgOverrides{
85+
pubfnlen(&self) -> usize{
86+
self.global.len() + self.selective.values().map(|it| it.len()).sum::<usize>()
87+
}
88+
89+
pubfnapply(&self,cfg_options:&mutCfgOptions,name:&str){
90+
if !self.global.is_empty(){
91+
cfg_options.apply_diff(self.global.clone());
92+
};
93+
ifletSome(diff) = self.selective.get(name){
94+
cfg_options.apply_diff(diff.clone());
95+
};
96+
}
97+
}

‎crates/project-model/src/env.rs‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//! Cargo-like environment variables injection.
2+
use base_db::Env;
3+
use rustc_hash::FxHashMap;
4+
use toolchain::Tool;
5+
6+
usecrate::{utf8_stdout,ManifestPath,PackageData,Sysroot,TargetKind};
7+
8+
/// Recreates the compile-time environment variables that Cargo sets.
9+
///
10+
/// Should be synced with
11+
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>
12+
///
13+
/// FIXME: ask Cargo to provide this data instead of re-deriving.
14+
pub(crate)fninject_cargo_package_env(env:&mutEnv,package:&PackageData){
15+
// FIXME: Missing variables:
16+
// CARGO_BIN_NAME, CARGO_BIN_EXE_<name>
17+
18+
let manifest_dir = package.manifest.parent();
19+
env.set("CARGO_MANIFEST_DIR", manifest_dir.as_str());
20+
21+
env.set("CARGO_PKG_VERSION", package.version.to_string());
22+
env.set("CARGO_PKG_VERSION_MAJOR", package.version.major.to_string());
23+
env.set("CARGO_PKG_VERSION_MINOR", package.version.minor.to_string());
24+
env.set("CARGO_PKG_VERSION_PATCH", package.version.patch.to_string());
25+
env.set("CARGO_PKG_VERSION_PRE", package.version.pre.to_string());
26+
27+
env.set("CARGO_PKG_AUTHORS", package.authors.join(":").clone());
28+
29+
env.set("CARGO_PKG_NAME", package.name.clone());
30+
env.set("CARGO_PKG_DESCRIPTION", package.description.as_deref().unwrap_or_default());
31+
env.set("CARGO_PKG_HOMEPAGE", package.homepage.as_deref().unwrap_or_default());
32+
env.set("CARGO_PKG_REPOSITORY", package.repository.as_deref().unwrap_or_default());
33+
env.set("CARGO_PKG_LICENSE", package.license.as_deref().unwrap_or_default());
34+
env.set(
35+
"CARGO_PKG_LICENSE_FILE",
36+
package.license_file.as_ref().map(ToString::to_string).unwrap_or_default(),
37+
);
38+
env.set(
39+
"CARGO_PKG_README",
40+
package.readme.as_ref().map(ToString::to_string).unwrap_or_default(),
41+
);
42+
43+
env.set(
44+
"CARGO_PKG_RUST_VERSION",
45+
package.rust_version.as_ref().map(ToString::to_string).unwrap_or_default(),
46+
);
47+
}
48+
49+
pub(crate)fninject_cargo_env(env:&mutEnv){
50+
env.set("CARGO",Tool::Cargo.path().to_string());
51+
}
52+
53+
pub(crate)fninject_rustc_tool_env(env:&mutEnv,cargo_name:&str,kind:TargetKind){
54+
_ = kind;
55+
// FIXME
56+
// if kind.is_executable() {
57+
// env.set("CARGO_BIN_NAME", cargo_name);
58+
// }
59+
env.set("CARGO_CRATE_NAME", cargo_name.replace('-',"_"));
60+
}
61+
62+
pub(crate)fncargo_config_env(
63+
cargo_toml:&ManifestPath,
64+
extra_env:&FxHashMap<String,String>,
65+
sysroot:Option<&Sysroot>,
66+
) -> FxHashMap<String,String>{
67+
letmut cargo_config = Sysroot::tool(sysroot,Tool::Cargo);
68+
cargo_config.envs(extra_env);
69+
cargo_config
70+
.current_dir(cargo_toml.parent())
71+
.args(["-Z","unstable-options","config","get","env"])
72+
.env("RUSTC_BOOTSTRAP","1");
73+
// if successful we receive `env.key.value = "value" per entry
74+
tracing::debug!("Discovering cargo config env by {:?}", cargo_config);
75+
utf8_stdout(cargo_config).map(parse_output_cargo_config_env).unwrap_or_default()
76+
}
77+
78+
fnparse_output_cargo_config_env(stdout:String) -> FxHashMap<String,String>{
79+
stdout
80+
.lines()
81+
.filter_map(|l| l.strip_prefix("env."))
82+
.filter_map(|l| l.split_once(".value = "))
83+
.map(|(key, value)| (key.to_owned(), value.trim_matches('"').to_owned()))
84+
.collect()
85+
}

‎crates/project-model/src/lib.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020
mod build_scripts;
2121
mod cargo_workspace;
22-
mod cfg_flag;
22+
mod cfg;
23+
mod env;
2324
mod manifest_path;
2425
mod project_json;
2526
mod rustc_cfg;
@@ -47,10 +48,11 @@ pub use crate::{
4748
CargoConfig,CargoFeatures,CargoWorkspace,Package,PackageData,PackageDependency,
4849
RustLibSource,Target,TargetData,TargetKind,
4950
},
51+
cfg::CfgOverrides,
5052
manifest_path::ManifestPath,
5153
project_json::{ProjectJson,ProjectJsonData},
5254
sysroot::Sysroot,
53-
workspace::{CfgOverrides,PackageRoot,ProjectWorkspace},
55+
workspace::{FileLoader,PackageRoot,ProjectWorkspace},
5456
};
5557

5658
#[derive(Debug,Clone,PartialEq,Eq,Hash,Ord,PartialOrd)]

‎crates/project-model/src/project_json.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use rustc_hash::FxHashMap;
5555
use serde::{de,Deserialize,Serialize};
5656
use span::Edition;
5757

58-
usecrate::cfg_flag::CfgFlag;
58+
usecrate::cfg::CfgFlag;
5959

6060
/// Roots and crates that compose this Rust project.
6161
#[derive(Clone,Debug,Eq,PartialEq)]

0 commit comments

Comments
 (0)