Skip to content

Commit 982b92f

Browse files
Merge #4431
4431: Store proc-macro result in salsa db r=matklad a=edwin0cheng Fixed #4315 Co-authored-by: Edwin Cheng <[email protected]>
2 parents 05db35d + 20f7068 commit 982b92f

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

crates/ra_hir_expand/src/db.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ impl TokenExpander {
3434
// FIXME switch these to ExpandResult as well
3535
TokenExpander::Builtin(it) => it.expand(db, id, tt).into(),
3636
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
37-
TokenExpander::ProcMacro(it) => it.expand(db, id, tt).into(),
37+
TokenExpander::ProcMacro(_) => {
38+
// We store the result in salsa db to prevent non-determinisc behavior in
39+
// some proc-macro implementation
40+
// See #4315 for details
41+
db.expand_proc_macro(id.into()).into()
42+
}
3843
}
3944
}
4045

@@ -75,6 +80,8 @@ pub trait AstDatabase: SourceDatabase {
7580

7681
#[salsa::interned]
7782
fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId;
83+
84+
fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>;
7885
}
7986

8087
/// This expands the given macro call, but with different arguments. This is
@@ -216,6 +223,33 @@ fn macro_expand_with_arg(
216223
(Some(Arc::new(tt)), err.map(|e| format!("{:?}", e)))
217224
}
218225

226+
pub(crate) fn expand_proc_macro(
227+
db: &dyn AstDatabase,
228+
id: MacroCallId,
229+
) -> Result<tt::Subtree, mbe::ExpandError> {
230+
let lazy_id = match id {
231+
MacroCallId::LazyMacro(id) => id,
232+
MacroCallId::EagerMacro(_) => unreachable!(),
233+
};
234+
235+
let loc = db.lookup_intern_macro(lazy_id);
236+
let macro_arg = match db.macro_arg(id) {
237+
Some(it) => it,
238+
None => {
239+
return Err(
240+
tt::ExpansionError::Unknown("No arguments for proc-macro".to_string()).into()
241+
)
242+
}
243+
};
244+
245+
let expander = match loc.def.kind {
246+
MacroDefKind::CustomDerive(expander) => expander,
247+
_ => unreachable!(),
248+
};
249+
250+
expander.expand(db, lazy_id, &macro_arg.0)
251+
}
252+
219253
pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> {
220254
match file_id.0 {
221255
HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()),

crates/ra_mbe/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub enum ParseError {
2222
RepetitionEmtpyTokenTree,
2323
}
2424

25-
#[derive(Debug, PartialEq, Eq)]
25+
#[derive(Debug, PartialEq, Eq, Clone)]
2626
pub enum ExpandError {
2727
NoMatchingRule,
2828
UnexpectedToken,

crates/ra_tt/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl Subtree {
243243

244244
pub mod buffer;
245245

246-
#[derive(Debug, PartialEq, Eq)]
246+
#[derive(Debug, PartialEq, Eq, Clone)]
247247
pub enum ExpansionError {
248248
IOError(String),
249249
JsonError(String),

0 commit comments

Comments
 (0)