Skip to content

Commit c1824b4

Browse files
Merge #6745
6745: Some more proc macro cleanups r=jonas-schievink a=jonas-schievink * Remove `ProcMacroClient::dummy` and just use `Option<ProcMacroClient>` instead * Remember the type of proc macros (later allows us to reject using an incorrect macro type) * Prepare a few internals for procedural attribute macros bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 9a88332 + 577d5f1 commit c1824b4

File tree

12 files changed

+84
-99
lines changed

12 files changed

+84
-99
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: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,17 @@ impl CrateDisplayName {
143143
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
144144
pub struct ProcMacroId(pub u32);
145145

146+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
147+
pub enum ProcMacroKind {
148+
CustomDerive,
149+
FuncLike,
150+
Attr,
151+
}
152+
146153
#[derive(Debug, Clone)]
147154
pub struct ProcMacro {
148155
pub name: SmolStr,
156+
pub kind: ProcMacroKind,
149157
pub expander: Arc<dyn TokenExpander>,
150158
}
151159

@@ -198,11 +206,8 @@ impl CrateGraph {
198206
display_name: Option<CrateDisplayName>,
199207
cfg_options: CfgOptions,
200208
env: Env,
201-
proc_macro: Vec<(SmolStr, Arc<dyn tt::TokenExpander>)>,
209+
proc_macro: Vec<ProcMacro>,
202210
) -> CrateId {
203-
let proc_macro =
204-
proc_macro.into_iter().map(|(name, it)| ProcMacro { name, expander: it }).collect();
205-
206211
let data = CrateData {
207212
root_file_id: file_id,
208213
edition,

crates/base_db/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub use crate::{
1414
change::Change,
1515
input::{
1616
CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env,
17-
ProcMacroId, SourceRoot, SourceRootId,
17+
ProcMacro, ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId,
1818
},
1919
};
2020
pub use salsa;

crates/hir_expand/src/proc_macro.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ impl ProcMacroExpander {
2626

2727
pub fn dummy(krate: CrateId) -> Self {
2828
// FIXME: Should store the name for better errors
29-
// FIXME: I think this is the second layer of "dummy" expansion, we should reduce that
3029
Self { krate, proc_macro_id: None }
3130
}
3231

crates/proc_macro_api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ crossbeam-channel = "0.5.0"
1717
jod-thread = "0.1.1"
1818

1919
tt = { path = "../tt", version = "0.0.0" }
20+
base_db = { path = "../base_db", version = "0.0.0" }

crates/proc_macro_api/src/lib.rs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ use std::{
1616
sync::Arc,
1717
};
1818

19+
use base_db::ProcMacro;
1920
use tt::{SmolStr, Subtree};
2021

2122
use crate::process::{ProcMacroProcessSrv, ProcMacroProcessThread};
2223

2324
pub use rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind};
2425

2526
#[derive(Debug, Clone)]
26-
pub struct ProcMacroProcessExpander {
27+
struct ProcMacroProcessExpander {
2728
process: Arc<ProcMacroProcessSrv>,
2829
dylib_path: PathBuf,
2930
name: SmolStr,
@@ -42,21 +43,24 @@ impl tt::TokenExpander for ProcMacroProcessExpander {
4243
fn expand(
4344
&self,
4445
subtree: &Subtree,
45-
_attr: Option<&Subtree>,
46+
attr: Option<&Subtree>,
4647
) -> Result<Subtree, tt::ExpansionError> {
47-
self.process.custom_derive(&self.dylib_path, subtree, &self.name)
48-
}
49-
}
48+
let task = ExpansionTask {
49+
macro_body: subtree.clone(),
50+
macro_name: self.name.to_string(),
51+
attributes: attr.cloned(),
52+
lib: self.dylib_path.to_path_buf(),
53+
};
5054

51-
#[derive(Debug)]
52-
enum ProcMacroClientKind {
53-
Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread },
54-
Dummy,
55+
let result: ExpansionResult = self.process.send_task(msg::Request::ExpansionMacro(task))?;
56+
Ok(result.expansion)
57+
}
5558
}
5659

5760
#[derive(Debug)]
5861
pub struct ProcMacroClient {
59-
kind: ProcMacroClientKind,
62+
process: Arc<ProcMacroProcessSrv>,
63+
thread: ProcMacroProcessThread,
6064
}
6165

6266
impl ProcMacroClient {
@@ -65,47 +69,35 @@ impl ProcMacroClient {
6569
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
6670
) -> io::Result<ProcMacroClient> {
6771
let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?;
68-
Ok(ProcMacroClient {
69-
kind: ProcMacroClientKind::Process { process: Arc::new(process), thread },
70-
})
72+
Ok(ProcMacroClient { process: Arc::new(process), thread })
7173
}
7274

73-
pub fn dummy() -> ProcMacroClient {
74-
ProcMacroClient { kind: ProcMacroClientKind::Dummy }
75-
}
75+
pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<ProcMacro> {
76+
let macros = match self.process.find_proc_macros(dylib_path) {
77+
Err(err) => {
78+
eprintln!("Failed to find proc macros. Error: {:#?}", err);
79+
return vec![];
80+
}
81+
Ok(macros) => macros,
82+
};
7683

77-
pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<(SmolStr, Arc<dyn tt::TokenExpander>)> {
78-
match &self.kind {
79-
ProcMacroClientKind::Dummy => vec![],
80-
ProcMacroClientKind::Process { process, .. } => {
81-
let macros = match process.find_proc_macros(dylib_path) {
82-
Err(err) => {
83-
eprintln!("Failed to find proc macros. Error: {:#?}", err);
84-
return vec![];
85-
}
86-
Ok(macros) => macros,
84+
macros
85+
.into_iter()
86+
.map(|(name, kind)| {
87+
let name = SmolStr::new(&name);
88+
let kind = match kind {
89+
ProcMacroKind::CustomDerive => base_db::ProcMacroKind::CustomDerive,
90+
ProcMacroKind::FuncLike => base_db::ProcMacroKind::FuncLike,
91+
ProcMacroKind::Attr => base_db::ProcMacroKind::Attr,
8792
};
93+
let expander: Arc<dyn tt::TokenExpander> = Arc::new(ProcMacroProcessExpander {
94+
process: self.process.clone(),
95+
name: name.clone(),
96+
dylib_path: dylib_path.into(),
97+
});
8898

89-
macros
90-
.into_iter()
91-
.filter_map(|(name, kind)| {
92-
match kind {
93-
ProcMacroKind::CustomDerive | ProcMacroKind::FuncLike => {
94-
let name = SmolStr::new(&name);
95-
let expander: Arc<dyn tt::TokenExpander> =
96-
Arc::new(ProcMacroProcessExpander {
97-
process: process.clone(),
98-
name: name.clone(),
99-
dylib_path: dylib_path.into(),
100-
});
101-
Some((name, expander))
102-
}
103-
// FIXME: Attribute macro are currently unsupported.
104-
ProcMacroKind::Attr => None,
105-
}
106-
})
107-
.collect()
108-
}
109-
}
99+
ProcMacro { name, kind, expander }
100+
})
101+
.collect()
110102
}
111103
}

crates/proc_macro_api/src/process.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ use std::{
1010
};
1111

1212
use crossbeam_channel::{bounded, Receiver, Sender};
13-
use tt::Subtree;
1413

1514
use crate::{
1615
msg::{ErrorCode, Message, Request, Response, ResponseError},
17-
rpc::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask, ProcMacroKind},
16+
rpc::{ListMacrosResult, ListMacrosTask, ProcMacroKind},
1817
};
1918

2019
#[derive(Debug, Default)]
@@ -58,23 +57,6 @@ impl ProcMacroProcessSrv {
5857
Ok(result.macros)
5958
}
6059

61-
pub(crate) fn custom_derive(
62-
&self,
63-
dylib_path: &Path,
64-
subtree: &Subtree,
65-
derive_name: &str,
66-
) -> Result<Subtree, tt::ExpansionError> {
67-
let task = ExpansionTask {
68-
macro_body: subtree.clone(),
69-
macro_name: derive_name.to_string(),
70-
attributes: None,
71-
lib: dylib_path.to_path_buf(),
72-
};
73-
74-
let result: ExpansionResult = self.send_task(Request::ExpansionMacro(task))?;
75-
Ok(result.expansion)
76-
}
77-
7860
pub(crate) fn send_task<R>(&self, req: Request) -> Result<R, tt::ExpansionError>
7961
where
8062
R: TryFrom<Response, Error = &'static str>,

crates/proc_macro_api/src/rpc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub struct ListMacrosTask {
1919
pub lib: PathBuf,
2020
}
2121

22-
#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
22+
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
2323
pub enum ProcMacroKind {
2424
CustomDerive,
2525
FuncLike,

crates/project_model/src/workspace.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
//! metadata` or `rust-project.json`) into representation stored in the salsa
33
//! database -- `CrateGraph`.
44
5-
use std::{fmt, fs, path::Component, process::Command};
5+
use std::{
6+
fmt, fs,
7+
path::{Component, Path},
8+
process::Command,
9+
};
610

711
use anyhow::{Context, Result};
8-
use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId};
12+
use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
913
use cfg::CfgOptions;
1014
use paths::{AbsPath, AbsPathBuf};
1115
use proc_macro_api::ProcMacroClient;
@@ -194,15 +198,20 @@ impl ProjectWorkspace {
194198
pub fn to_crate_graph(
195199
&self,
196200
target: Option<&str>,
197-
proc_macro_client: &ProcMacroClient,
201+
proc_macro_client: Option<&ProcMacroClient>,
198202
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
199203
) -> CrateGraph {
204+
let proc_macro_loader = |path: &Path| match proc_macro_client {
205+
Some(client) => client.by_dylib_path(path),
206+
None => Vec::new(),
207+
};
208+
200209
let mut crate_graph = match self {
201210
ProjectWorkspace::Json { project, sysroot } => {
202-
project_json_to_crate_graph(target, proc_macro_client, load, project, sysroot)
211+
project_json_to_crate_graph(target, &proc_macro_loader, load, project, sysroot)
203212
}
204213
ProjectWorkspace::Cargo { cargo, sysroot, rustc } => {
205-
cargo_to_crate_graph(target, proc_macro_client, load, cargo, sysroot, rustc)
214+
cargo_to_crate_graph(target, &proc_macro_loader, load, cargo, sysroot, rustc)
206215
}
207216
};
208217
if crate_graph.patch_cfg_if() {
@@ -216,7 +225,7 @@ impl ProjectWorkspace {
216225

217226
fn project_json_to_crate_graph(
218227
target: Option<&str>,
219-
proc_macro_client: &ProcMacroClient,
228+
proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>,
220229
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
221230
project: &ProjectJson,
222231
sysroot: &Option<Sysroot>,
@@ -236,8 +245,7 @@ fn project_json_to_crate_graph(
236245
})
237246
.map(|(crate_id, krate, file_id)| {
238247
let env = krate.env.clone().into_iter().collect();
239-
let proc_macro =
240-
krate.proc_macro_dylib_path.clone().map(|it| proc_macro_client.by_dylib_path(&it));
248+
let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it));
241249

242250
let target = krate.target.as_deref().or(target);
243251
let target_cfgs =
@@ -279,7 +287,7 @@ fn project_json_to_crate_graph(
279287

280288
fn cargo_to_crate_graph(
281289
target: Option<&str>,
282-
proc_macro_client: &ProcMacroClient,
290+
proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>,
283291
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
284292
cargo: &CargoWorkspace,
285293
sysroot: &Sysroot,
@@ -309,7 +317,7 @@ fn cargo_to_crate_graph(
309317
&mut crate_graph,
310318
&cargo[pkg],
311319
&cfg_options,
312-
proc_macro_client,
320+
proc_macro_loader,
313321
file_id,
314322
);
315323
if cargo[tgt].kind == TargetKind::Lib {
@@ -385,7 +393,7 @@ fn cargo_to_crate_graph(
385393
&mut crate_graph,
386394
&rustc_workspace[pkg],
387395
&cfg_options,
388-
proc_macro_client,
396+
proc_macro_loader,
389397
file_id,
390398
);
391399
pkg_to_lib_crate.insert(pkg, crate_id);
@@ -433,7 +441,7 @@ fn add_target_crate_root(
433441
crate_graph: &mut CrateGraph,
434442
pkg: &cargo_workspace::PackageData,
435443
cfg_options: &CfgOptions,
436-
proc_macro_client: &ProcMacroClient,
444+
proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>,
437445
file_id: FileId,
438446
) -> CrateId {
439447
let edition = pkg.edition;
@@ -452,11 +460,8 @@ fn add_target_crate_root(
452460
env.set("OUT_DIR", out_dir);
453461
}
454462
}
455-
let proc_macro = pkg
456-
.proc_macro_dylib_path
457-
.as_ref()
458-
.map(|it| proc_macro_client.by_dylib_path(&it))
459-
.unwrap_or_default();
463+
let proc_macro =
464+
pkg.proc_macro_dylib_path.as_ref().map(|it| proc_macro_loader(&it)).unwrap_or_default();
460465

461466
let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone());
462467
let crate_id = crate_graph.add_crate_root(

crates/rust-analyzer/src/cli/load_cargo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ pub fn load_cargo(
3333

3434
let proc_macro_client = if with_proc_macro {
3535
let path = std::env::current_exe()?;
36-
ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()
36+
Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap())
3737
} else {
38-
ProcMacroClient::dummy()
38+
None
3939
};
4040

41-
let crate_graph = ws.to_crate_graph(None, &proc_macro_client, &mut |path: &AbsPath| {
41+
let crate_graph = ws.to_crate_graph(None, proc_macro_client.as_ref(), &mut |path: &AbsPath| {
4242
let contents = loader.load_sync(path);
4343
let path = vfs::VfsPath::from(path.to_path_buf());
4444
vfs.set_file_contents(path.clone(), contents);

0 commit comments

Comments
 (0)