impl HasSource for MacroDef {
type Ast = ast::Macro;
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
- let ast_id = self.id.ast_id?;
+ let ast_id = self.id.ast_id()?;
Some(InFile { file_id: ast_id.file_id, value: ast_id.to_node(db.upcast()) })
}
}
/// Indicate it is a derive macro
pub fn is_derive_macro(&self) -> bool {
- matches!(self.id.kind, MacroDefKind::ProcMacro(_) | MacroDefKind::BuiltInDerive(_))
+ // FIXME: wrong for `ProcMacro`
+ matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..))
}
}
&mut self,
src: InFile<ast::MacroRules>,
) -> Option<MacroDefId> {
- let kind = MacroDefKind::Declarative;
+ let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
+ let ast_id = AstId::new(src.file_id, file_ast_id.upcast());
+ let kind = MacroDefKind::Declarative(ast_id);
let file_id = src.file_id.original_file(self.db.upcast());
let krate = self.file_to_def(file_id).get(0).copied()?.krate();
- let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value);
- let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
- Some(MacroDefId { krate, ast_id, kind, local_inner: false })
+ Some(MacroDefId { krate, kind, local_inner: false })
}
pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> {
},
AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
AttrDefId::MacroDefId(it) => {
- it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
+ it.ast_id().map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
}
AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
dep::fmt (t)
dep::format (f)
dep::Fmt (v)
- dep::fmt::Display (t)
+ dep::Fmt (m)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
- dep::Fmt (m)
+ dep::fmt::Display (t)
"#]],
);
expect![[r#"
dep::fmt (t)
dep::Fmt (v)
+ dep::Fmt (m)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
- dep::Fmt (m)
"#]],
);
expect![[r#"
dep::fmt (t)
dep::Fmt (v)
- dep::fmt::Display (t)
+ dep::Fmt (m)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
- dep::Fmt (m)
+ dep::fmt::Display (t)
"#]],
);
}
expect![[r#"
dep::fmt (t)
dep::Fmt (v)
- dep::fmt::Display (t)
+ dep::Fmt (m)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
- dep::Fmt (m)
+ dep::fmt::Display (t)
"#]],
);
expect![[r#"
dep::fmt (t)
dep::Fmt (v)
+ dep::Fmt (m)
dep::Fmt (t)
dep::fmt::Display::fmt (a)
- dep::Fmt (m)
"#]],
);
}
Query::new("".to_string()).limit(2),
expect![[r#"
dep::fmt (t)
- dep::Fmt (t)
dep::Fmt (m)
+ dep::Fmt (t)
dep::Fmt (v)
"#]],
);
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
- let res = if let MacroDefKind::BuiltInEager(_) = def.kind {
+ let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
self.exports_proc_macros = true;
let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
Some((_, expander)) => MacroDefId {
- ast_id: None,
krate: self.def_map.krate,
kind: MacroDefKind::ProcMacro(*expander),
local_inner: false,
},
None => MacroDefId {
- ast_id: None,
krate: self.def_map.krate,
kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)),
local_inner: false,
// Case 2: normal `macro_rules!` macro
let macro_id = MacroDefId {
- ast_id: Some(ast_id),
krate: self.def_collector.def_map.krate,
- kind: MacroDefKind::Declarative,
+ kind: MacroDefKind::Declarative(ast_id),
local_inner: is_local_inner,
};
self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
let expander = BuiltinDeriveExpander::find_by_name(ident)?;
Some(MacroDefId {
krate,
- ast_id: Some(ast_id),
- kind: MacroDefKind::BuiltInDerive(expander),
+ kind: MacroDefKind::BuiltInDerive(expander, ast_id),
local_inner: false,
})
}
let loc = MacroCallLoc {
def: MacroDefId {
krate: CrateId(0),
- ast_id: Some(macro_ast_id),
- kind: MacroDefKind::BuiltInDerive(expander),
+ kind: MacroDefKind::BuiltInDerive(expander, macro_ast_id),
local_inner: false,
},
krate: CrateId(0),
match kind {
Either::Left(kind) => Some(MacroDefId {
krate,
- ast_id: Some(ast_id),
- kind: MacroDefKind::BuiltIn(kind),
+ kind: MacroDefKind::BuiltIn(kind, ast_id),
local_inner: false,
}),
Either::Right(kind) => Some(MacroDefId {
krate,
- ast_id: Some(ast_id),
- kind: MacroDefKind::BuiltInEager(kind),
+ kind: MacroDefKind::BuiltInEager(kind, ast_id),
local_inner: false,
}),
}
let macro_call = macro_calls.pop().unwrap();
let expander = find_by_name(¯o_rules.name().unwrap().as_name()).unwrap();
+ let ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules));
let krate = CrateId(0);
let file_id = match expander {
// the first one should be a macro_rules
let def = MacroDefId {
krate: CrateId(0),
- ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules))),
- kind: MacroDefKind::BuiltIn(expander),
+ kind: MacroDefKind::BuiltIn(expander, ast_id),
local_inner: false,
};
// the first one should be a macro_rules
let def = MacroDefId {
krate,
- ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules))),
- kind: MacroDefKind::BuiltInEager(expander),
+ kind: MacroDefKind::BuiltInEager(expander, ast_id),
local_inner: false,
};
fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
match id.kind {
- MacroDefKind::Declarative => {
- let macro_rules = match id.ast_id?.to_node(db) {
+ MacroDefKind::Declarative(ast_id) => {
+ let macro_rules = match ast_id.to_node(db) {
syntax::ast::Macro::MacroRules(mac) => mac,
syntax::ast::Macro::MacroDef(_) => return None,
};
};
Some(Arc::new((TokenExpander::MacroRules(rules), tmap)))
}
- MacroDefKind::BuiltIn(expander) => {
+ MacroDefKind::BuiltIn(expander, _) => {
Some(Arc::new((TokenExpander::Builtin(expander), mbe::TokenMap::default())))
}
- MacroDefKind::BuiltInDerive(expander) => {
+ MacroDefKind::BuiltInDerive(expander, _) => {
Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default())))
}
- MacroDefKind::BuiltInEager(_) => None,
+ MacroDefKind::BuiltInEager(..) => None,
MacroDefKind::ProcMacro(expander) => {
Some(Arc::new((TokenExpander::ProcMacro(expander), mbe::TokenMap::default())))
}
let subtree =
diagnostic_sink.option(to_subtree(&result), || err("failed to parse macro result"))?;
- if let MacroDefKind::BuiltInEager(eager) = def.kind {
+ if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
let res = eager.expand(db, arg_id, &subtree);
let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?;
let def = diagnostic_sink
.option_with(|| macro_resolver(child.path()?), || err("failed to resolve macro"))?;
let insert = match def.kind {
- MacroDefKind::BuiltInEager(_) => {
+ MacroDefKind::BuiltInEager(..) => {
let id: MacroCallId = expand_eager_macro(
db,
krate,
db.parse_or_expand(id.as_file())
.expect("successful macro expansion should be parseable")
}
- MacroDefKind::Declarative
- | MacroDefKind::BuiltIn(_)
- | MacroDefKind::BuiltInDerive(_)
+ MacroDefKind::Declarative(_)
+ | MacroDefKind::BuiltIn(..)
+ | MacroDefKind::BuiltInDerive(..)
| MacroDefKind::ProcMacro(_) => {
let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate);
let val = diagnostic_sink.expand_result_option(res)?;
) -> Option<HygieneInfo> {
let arg_tt = loc.kind.arg(db)?;
- let def_offset = loc.def.ast_id.and_then(|id| {
+ let def_offset = loc.def.ast_id().and_then(|id| {
let def_tt = match id.to_node(db) {
ast::Macro::MacroRules(mac) => mac.token_tree()?.syntax().text_range().start(),
ast::Macro::MacroDef(_) => return None,
let loc = db.lookup_intern_macro(id);
let info = make_hygiene_info(db, macro_file, &loc);
match loc.def.kind {
- MacroDefKind::Declarative => {
+ MacroDefKind::Declarative(_) => {
(info, Some(loc.def.krate), loc.def.local_inner)
}
- MacroDefKind::BuiltIn(_) => (info, Some(loc.def.krate), false),
- MacroDefKind::BuiltInDerive(_) => (info, None, false),
- MacroDefKind::BuiltInEager(_) => (info, None, false),
+ MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false),
+ MacroDefKind::BuiltInDerive(..) => (info, None, false),
+ MacroDefKind::BuiltInEager(..) => (info, None, false),
MacroDefKind::ProcMacro(_) => (info, None, false),
}
}
let arg_tt = loc.kind.arg(db)?;
- let def = loc.def.ast_id.and_then(|id| {
+ let def = loc.def.ast_id().and_then(|id| {
let def_tt = match id.to_node(db) {
ast::Macro::MacroRules(mac) => mac.token_tree()?,
ast::Macro::MacroDef(_) => return None,
};
let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
let item = match loc.def.kind {
- MacroDefKind::BuiltInDerive(_) => loc.kind.node(db),
+ MacroDefKind::BuiltInDerive(..) => loc.kind.node(db),
_ => return None,
};
Some(item.with_value(ast::Item::cast(item.value.clone())?))
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroDefId {
pub krate: CrateId,
- pub ast_id: Option<AstId<ast::Macro>>,
pub kind: MacroDefKind,
pub local_inner: bool,
) -> LazyMacroId {
db.intern_macro(MacroCallLoc { def: self, krate, kind })
}
+
+ pub fn ast_id(&self) -> Option<AstId<ast::Macro>> {
+ let id = match &self.kind {
+ MacroDefKind::Declarative(id) => id,
+ MacroDefKind::BuiltIn(_, id) => id,
+ MacroDefKind::BuiltInDerive(_, id) => id,
+ MacroDefKind::BuiltInEager(_, id) => id,
+ MacroDefKind::ProcMacro(_) => return None,
+ };
+ Some(*id)
+ }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MacroDefKind {
- Declarative,
- BuiltIn(BuiltinFnLikeExpander),
+ Declarative(AstId<ast::Macro>),
+ BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>),
// FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander
- BuiltInDerive(BuiltinDeriveExpander),
- BuiltInEager(EagerExpander),
+ BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>),
+ BuiltInEager(EagerExpander, AstId<ast::Macro>),
ProcMacro(ProcMacroExpander),
}