mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
Store proc-macro result in salsa db
This commit is contained in:
parent
6fde7f1b6b
commit
20f7068b68
3 changed files with 37 additions and 3 deletions
|
@ -34,7 +34,12 @@ impl TokenExpander {
|
||||||
// FIXME switch these to ExpandResult as well
|
// FIXME switch these to ExpandResult as well
|
||||||
TokenExpander::Builtin(it) => it.expand(db, id, tt).into(),
|
TokenExpander::Builtin(it) => it.expand(db, id, tt).into(),
|
||||||
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
|
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
|
||||||
TokenExpander::ProcMacro(it) => it.expand(db, id, tt).into(),
|
TokenExpander::ProcMacro(_) => {
|
||||||
|
// We store the result in salsa db to prevent non-determinisc behavior in
|
||||||
|
// some proc-macro implementation
|
||||||
|
// See #4315 for details
|
||||||
|
db.expand_proc_macro(id.into()).into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +80,8 @@ pub trait AstDatabase: SourceDatabase {
|
||||||
|
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId;
|
fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId;
|
||||||
|
|
||||||
|
fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This expands the given macro call, but with different arguments. This is
|
/// This expands the given macro call, but with different arguments. This is
|
||||||
|
@ -216,6 +223,33 @@ fn macro_expand_with_arg(
|
||||||
(Some(Arc::new(tt)), err.map(|e| format!("{:?}", e)))
|
(Some(Arc::new(tt)), err.map(|e| format!("{:?}", e)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn expand_proc_macro(
|
||||||
|
db: &dyn AstDatabase,
|
||||||
|
id: MacroCallId,
|
||||||
|
) -> Result<tt::Subtree, mbe::ExpandError> {
|
||||||
|
let lazy_id = match id {
|
||||||
|
MacroCallId::LazyMacro(id) => id,
|
||||||
|
MacroCallId::EagerMacro(_) => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let loc = db.lookup_intern_macro(lazy_id);
|
||||||
|
let macro_arg = match db.macro_arg(id) {
|
||||||
|
Some(it) => it,
|
||||||
|
None => {
|
||||||
|
return Err(
|
||||||
|
tt::ExpansionError::Unknown("No arguments for proc-macro".to_string()).into()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expander = match loc.def.kind {
|
||||||
|
MacroDefKind::CustomDerive(expander) => expander,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
expander.expand(db, lazy_id, ¯o_arg.0)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> {
|
pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> {
|
||||||
match file_id.0 {
|
match file_id.0 {
|
||||||
HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()),
|
HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()),
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub enum ParseError {
|
||||||
RepetitionEmtpyTokenTree,
|
RepetitionEmtpyTokenTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum ExpandError {
|
pub enum ExpandError {
|
||||||
NoMatchingRule,
|
NoMatchingRule,
|
||||||
UnexpectedToken,
|
UnexpectedToken,
|
||||||
|
|
|
@ -243,7 +243,7 @@ impl Subtree {
|
||||||
|
|
||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum ExpansionError {
|
pub enum ExpansionError {
|
||||||
IOError(String),
|
IOError(String),
|
||||||
JsonError(String),
|
JsonError(String),
|
||||||
|
|
Loading…
Reference in a new issue