Skip to content

Commit f55b44c

Browse files
committed
fix: Fix, clarify and require a value for proc_macro_cwd of CrateData
1 parent 2e1ff25 commit f55b44c

File tree

16 files changed

+142
-67
lines changed

16 files changed

+142
-67
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/base-db/src/input.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,11 @@ pub struct CrateData<Id> {
303303
pub dependencies: Vec<Dependency<Id>>,
304304
pub origin: CrateOrigin,
305305
pub is_proc_macro: bool,
306-
/// The working directory to run proc-macros in. This is the workspace root of the cargo workspace
307-
/// for workspace members, the crate manifest dir otherwise.
308-
pub proc_macro_cwd: Option<AbsPathBuf>,
306+
/// The working directory to run proc-macros in invoked in the context of this crate.
307+
/// This is the workspace root of the cargo workspace for workspace members, the crate manifest
308+
/// dir otherwise.
309+
// FIXME: This ought to be a `VfsPath` or something opaque.
310+
pub proc_macro_cwd: Arc<AbsPathBuf>,
309311
}
310312

311313
pub type CrateDataBuilder = CrateData<CrateBuilderId>;
@@ -425,7 +427,7 @@ impl CrateGraphBuilder {
425427
mut env: Env,
426428
origin: CrateOrigin,
427429
is_proc_macro: bool,
428-
proc_macro_cwd: Option<AbsPathBuf>,
430+
proc_macro_cwd: Arc<AbsPathBuf>,
429431
ws_data: Arc<CrateWorkspaceData>,
430432
) -> CrateBuilderId {
431433
env.entries.shrink_to_fit();
@@ -861,6 +863,7 @@ impl fmt::Display for CyclicDependenciesError {
861863
#[cfg(test)]
862864
mod tests {
863865
use triomphe::Arc;
866+
use vfs::AbsPathBuf;
864867

865868
use crate::{CrateWorkspaceData, DependencyBuilder};
866869

@@ -883,7 +886,7 @@ mod tests {
883886
Env::default(),
884887
CrateOrigin::Local { repo: None, name: None },
885888
false,
886-
None,
889+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
887890
empty_ws_data(),
888891
);
889892
let crate2 = graph.add_crate_root(
@@ -896,7 +899,7 @@ mod tests {
896899
Env::default(),
897900
CrateOrigin::Local { repo: None, name: None },
898901
false,
899-
None,
902+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
900903
empty_ws_data(),
901904
);
902905
let crate3 = graph.add_crate_root(
@@ -909,7 +912,7 @@ mod tests {
909912
Env::default(),
910913
CrateOrigin::Local { repo: None, name: None },
911914
false,
912-
None,
915+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
913916
empty_ws_data(),
914917
);
915918
assert!(
@@ -942,7 +945,7 @@ mod tests {
942945
Env::default(),
943946
CrateOrigin::Local { repo: None, name: None },
944947
false,
945-
None,
948+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
946949
empty_ws_data(),
947950
);
948951
let crate2 = graph.add_crate_root(
@@ -955,7 +958,7 @@ mod tests {
955958
Env::default(),
956959
CrateOrigin::Local { repo: None, name: None },
957960
false,
958-
None,
961+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
959962
empty_ws_data(),
960963
);
961964
assert!(
@@ -983,7 +986,7 @@ mod tests {
983986
Env::default(),
984987
CrateOrigin::Local { repo: None, name: None },
985988
false,
986-
None,
989+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
987990
empty_ws_data(),
988991
);
989992
let crate2 = graph.add_crate_root(
@@ -996,7 +999,7 @@ mod tests {
996999
Env::default(),
9971000
CrateOrigin::Local { repo: None, name: None },
9981001
false,
999-
None,
1002+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
10001003
empty_ws_data(),
10011004
);
10021005
let crate3 = graph.add_crate_root(
@@ -1009,7 +1012,7 @@ mod tests {
10091012
Env::default(),
10101013
CrateOrigin::Local { repo: None, name: None },
10111014
false,
1012-
None,
1015+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
10131016
empty_ws_data(),
10141017
);
10151018
assert!(
@@ -1037,7 +1040,7 @@ mod tests {
10371040
Env::default(),
10381041
CrateOrigin::Local { repo: None, name: None },
10391042
false,
1040-
None,
1043+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
10411044
empty_ws_data(),
10421045
);
10431046
let crate2 = graph.add_crate_root(
@@ -1050,7 +1053,7 @@ mod tests {
10501053
Env::default(),
10511054
CrateOrigin::Local { repo: None, name: None },
10521055
false,
1053-
None,
1056+
Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())),
10541057
empty_ws_data(),
10551058
);
10561059
assert!(

crates/hir-def/src/macro_expansion_tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
362362
_: Span,
363363
_: Span,
364364
_: Span,
365-
_: Option<String>,
365+
_: String,
366366
) -> Result<TopSubtree, ProcMacroExpansionError> {
367367
let (parse, _) = syntax_bridge::token_tree_to_syntax_node(
368368
subtree,

crates/hir-def/src/nameres/tests/incremental.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub const BAZ: u32 = 0;
5252
{
5353
// Add a dependency a -> b.
5454
let mut new_crate_graph = CrateGraphBuilder::default();
55+
5556
let mut add_crate = |crate_name, root_file_idx: usize| {
5657
new_crate_graph.add_crate_root(
5758
files[root_file_idx].file_id(),
@@ -63,7 +64,13 @@ pub const BAZ: u32 = 0;
6364
Env::default(),
6465
CrateOrigin::Local { repo: None, name: Some(Symbol::intern(crate_name)) },
6566
false,
66-
None,
67+
Arc::new(
68+
// FIXME: This is less than ideal
69+
TryFrom::try_from(
70+
&*std::env::current_dir().unwrap().as_path().to_string_lossy(),
71+
)
72+
.unwrap(),
73+
),
6774
Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None }),
6875
)
6976
};

crates/hir-expand/src/proc_macro.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe + AsAny {
4141
def_site: Span,
4242
call_site: Span,
4343
mixed_site: Span,
44-
current_dir: Option<String>,
44+
current_dir: String,
4545
) -> Result<tt::TopSubtree, ProcMacroExpansionError>;
4646

4747
fn eq_dyn(&self, other: &dyn ProcMacroExpander) -> bool;
@@ -318,8 +318,8 @@ impl CustomProcMacroExpander {
318318

319319
// Proc macros have access to the environment variables of the invoking crate.
320320
let env = calling_crate.env(db);
321-
let current_dir =
322-
calling_crate.data(db).proc_macro_cwd.as_deref().map(ToString::to_string);
321+
// FIXME: Can we avoid the string allocation here?
322+
let current_dir = calling_crate.data(db).proc_macro_cwd.to_string();
323323

324324
match proc_macro.expander.expand(
325325
tt,

crates/ide/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ impl Analysis {
244244
// FIXME: cfg options
245245
// Default to enable test for single file.
246246
let mut cfg_options = CfgOptions::default();
247+
248+
// FIXME: This is less than ideal
249+
let proc_macro_cwd = Arc::new(
250+
TryFrom::try_from(&*std::env::current_dir().unwrap().as_path().to_string_lossy())
251+
.unwrap(),
252+
);
247253
cfg_options.insert_atom(sym::test.clone());
248254
crate_graph.add_crate_root(
249255
file_id,
@@ -255,7 +261,7 @@ impl Analysis {
255261
Env::default(),
256262
CrateOrigin::Local { repo: None, name: None },
257263
false,
258-
None,
264+
proc_macro_cwd,
259265
Arc::new(CrateWorkspaceData {
260266
data_layout: Err("fixture has no layout".into()),
261267
toolchain: None,

crates/load-cargo/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ impl ProcMacroExpander for Expander {
496496
def_site: Span,
497497
call_site: Span,
498498
mixed_site: Span,
499-
current_dir: Option<String>,
499+
current_dir: String,
500500
) -> Result<tt::TopSubtree<Span>, ProcMacroExpansionError> {
501501
match self.0.expand(
502502
subtree.view(),

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl ProcMacro {
170170
def_site: Span,
171171
call_site: Span,
172172
mixed_site: Span,
173-
current_dir: Option<String>,
173+
current_dir: String,
174174
) -> Result<Result<tt::TopSubtree<Span>, PanicMessage>, ServerError> {
175175
let version = self.process.version();
176176

@@ -198,7 +198,7 @@ impl ProcMacro {
198198
},
199199
lib: self.dylib_path.to_path_buf().into(),
200200
env,
201-
current_dir,
201+
current_dir: Some(current_dir),
202202
};
203203

204204
let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;

crates/project-model/src/workspace.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ fn project_json_to_crate_graph(
988988
);
989989

990990
let mut cfg_cache: FxHashMap<&str, Vec<CfgAtom>> = FxHashMap::default();
991+
let project_root = Arc::new(project.project_root().to_path_buf());
991992

992993
let idx_to_crate_id: FxHashMap<CrateArrayIdx, _> = project
993994
.crates()
@@ -1067,7 +1068,10 @@ fn project_json_to_crate_graph(
10671068
CrateOrigin::Local { repo: None, name: None }
10681069
},
10691070
*is_proc_macro,
1070-
proc_macro_cwd.clone(),
1071+
match proc_macro_cwd {
1072+
Some(path) => Arc::new(path.clone()),
1073+
None => project_root.clone(),
1074+
},
10711075
crate_ws_data.clone(),
10721076
);
10731077
debug!(
@@ -1139,6 +1143,7 @@ fn cargo_to_crate_graph(
11391143
let mut pkg_crates = FxHashMap::default();
11401144
// Does any crate signal to rust-analyzer that they need the rustc_private crates?
11411145
let mut has_private = false;
1146+
let workspace_proc_macro_cwd = Arc::new(cargo.workspace_root().to_path_buf());
11421147

11431148
// Next, create crates for each package, target pair
11441149
for pkg in cargo.packages() {
@@ -1161,8 +1166,9 @@ fn cargo_to_crate_graph(
11611166

11621167
let mut lib_tgt = None;
11631168
for &tgt in cargo[pkg].targets.iter() {
1169+
let pkg_data = &cargo[pkg];
11641170
if !matches!(cargo[tgt].kind, TargetKind::Lib { .. })
1165-
&& (!cargo[pkg].is_member || cargo.is_sysroot())
1171+
&& (!pkg_data.is_member || cargo.is_sysroot())
11661172
{
11671173
// For non-workspace-members, Cargo does not resolve dev-dependencies, so we don't
11681174
// add any targets except the library target, since those will not work correctly if
@@ -1176,7 +1182,6 @@ fn cargo_to_crate_graph(
11761182
let Some(file_id) = load(root) else { continue };
11771183

11781184
let build_data = build_scripts.get_output(pkg);
1179-
let pkg_data = &cargo[pkg];
11801185
let crate_id = add_target_crate_root(
11811186
crate_graph,
11821187
proc_macros,
@@ -1203,6 +1208,11 @@ fn cargo_to_crate_graph(
12031208
}
12041209
},
12051210
crate_ws_data.clone(),
1211+
if pkg_data.is_member {
1212+
workspace_proc_macro_cwd.clone()
1213+
} else {
1214+
Arc::new(pkg_data.manifest.parent().to_path_buf())
1215+
},
12061216
);
12071217
if let TargetKind::Lib { .. } = kind {
12081218
lib_tgt = Some((crate_id, name.clone()));
@@ -1364,14 +1374,15 @@ fn detached_file_to_crate_graph(
13641374
name: display_name.map(|n| n.canonical_name().to_owned()),
13651375
},
13661376
false,
1367-
None,
1377+
Arc::new(detached_file.parent().to_path_buf()),
13681378
crate_ws_data,
13691379
);
13701380

13711381
public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
13721382
(crate_graph, FxHashMap::default())
13731383
}
13741384

1385+
// FIXME: There shouldn't really be a need for duplicating all of this?
13751386
fn handle_rustc_crates(
13761387
crate_graph: &mut CrateGraphBuilder,
13771388
proc_macros: &mut ProcMacroPaths,
@@ -1391,6 +1402,7 @@ fn handle_rustc_crates(
13911402
// The root package of the rustc-dev component is rustc_driver, so we match that
13921403
let root_pkg =
13931404
rustc_workspace.packages().find(|&package| rustc_workspace[package].name == "rustc_driver");
1405+
let workspace_proc_macro_cwd = Arc::new(cargo.workspace_root().to_path_buf());
13941406
// The rustc workspace might be incomplete (such as if rustc-dev is not
13951407
// installed for the current toolchain) and `rustc_source` is set to discover.
13961408
if let Some(root_pkg) = root_pkg {
@@ -1404,14 +1416,15 @@ fn handle_rustc_crates(
14041416
if rustc_pkg_crates.contains_key(&pkg) {
14051417
continue;
14061418
}
1407-
for dep in &rustc_workspace[pkg].dependencies {
1419+
let pkg_data = &rustc_workspace[pkg];
1420+
for dep in &pkg_data.dependencies {
14081421
queue.push_back(dep.pkg);
14091422
}
14101423

14111424
let mut cfg_options = cfg_options.clone();
1412-
override_cfg.apply(&mut cfg_options, &rustc_workspace[pkg].name);
1425+
override_cfg.apply(&mut cfg_options, &pkg_data.name);
14131426

1414-
for &tgt in rustc_workspace[pkg].targets.iter() {
1427+
for &tgt in pkg_data.targets.iter() {
14151428
let kind @ TargetKind::Lib { is_proc_macro } = rustc_workspace[tgt].kind else {
14161429
continue;
14171430
};
@@ -1421,14 +1434,19 @@ fn handle_rustc_crates(
14211434
crate_graph,
14221435
proc_macros,
14231436
rustc_workspace,
1424-
&rustc_workspace[pkg],
1437+
&pkg_data,
14251438
build_scripts.get_output(pkg).zip(Some(build_scripts.error().is_some())),
14261439
cfg_options.clone(),
14271440
file_id,
14281441
&rustc_workspace[tgt].name,
14291442
kind,
1430-
CrateOrigin::Rustc { name: Symbol::intern(&rustc_workspace[pkg].name) },
1443+
CrateOrigin::Rustc { name: Symbol::intern(&pkg_data.name) },
14311444
crate_ws_data.clone(),
1445+
if pkg_data.is_member {
1446+
workspace_proc_macro_cwd.clone()
1447+
} else {
1448+
Arc::new(pkg_data.manifest.parent().to_path_buf())
1449+
},
14321450
);
14331451
pkg_to_lib_crate.insert(pkg, crate_id);
14341452
// Add dependencies on core / std / alloc for this crate
@@ -1490,6 +1508,7 @@ fn add_target_crate_root(
14901508
kind: TargetKind,
14911509
origin: CrateOrigin,
14921510
crate_ws_data: Arc<CrateWorkspaceData>,
1511+
proc_macro_cwd: Arc<AbsPathBuf>,
14931512
) -> CrateBuilderId {
14941513
let edition = pkg.edition;
14951514
let potential_cfg_options = if pkg.features.is_empty() {
@@ -1531,9 +1550,7 @@ fn add_target_crate_root(
15311550
env,
15321551
origin,
15331552
matches!(kind, TargetKind::Lib { is_proc_macro: true }),
1534-
matches!(kind, TargetKind::Lib { is_proc_macro: true }).then(|| {
1535-
if pkg.is_member { cargo.workspace_root() } else { pkg.manifest.parent() }.to_path_buf()
1536-
}),
1553+
proc_macro_cwd,
15371554
crate_ws_data,
15381555
);
15391556
if let TargetKind::Lib { is_proc_macro: true } = kind {
@@ -1706,7 +1723,7 @@ fn sysroot_to_crate_graph(
17061723
Env::default(),
17071724
CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
17081725
false,
1709-
None,
1726+
Arc::new(stitched[krate].root.parent().to_path_buf()),
17101727
crate_ws_data.clone(),
17111728
);
17121729
Some((krate, crate_id))

0 commit comments

Comments
 (0)