Make macro def krate mandatory

Refactors builtin derive support to go through proper name resolution
This commit is contained in:
Jonas Schievink 2020-12-15 20:33:05 +01:00
parent c31c3246a8
commit b238ddd21a
14 changed files with 91 additions and 42 deletions

View file

@ -8,7 +8,7 @@ use syntax::{
match_ast,
};
use crate::{db::AstDatabase, name, quote, LazyMacroId, MacroDefId, MacroDefKind};
use crate::{db::AstDatabase, name, quote, AstId, CrateId, LazyMacroId, MacroDefId, MacroDefKind};
macro_rules! register_builtin {
( $($trait:ident => $expand:ident),* ) => {
@ -29,16 +29,15 @@ macro_rules! register_builtin {
};
expander(db, id, tt)
}
fn find_by_name(name: &name::Name) -> Option<Self> {
match name {
$( id if id == &name::name![$trait] => Some(BuiltinDeriveExpander::$trait), )*
_ => None,
}
}
}
pub fn find_builtin_derive(ident: &name::Name) -> Option<MacroDefId> {
let kind = match ident {
$( id if id == &name::name![$trait] => BuiltinDeriveExpander::$trait, )*
_ => return None,
};
Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind), local_inner: false })
}
};
}
@ -54,6 +53,20 @@ register_builtin! {
PartialEq => partial_eq_expand
}
pub fn find_builtin_derive(
ident: &name::Name,
krate: CrateId,
ast_id: AstId<ast::Macro>,
) -> Option<MacroDefId> {
let expander = BuiltinDeriveExpander::find_by_name(ident)?;
Some(MacroDefId {
krate,
ast_id: Some(ast_id),
kind: MacroDefKind::BuiltInDerive(expander),
local_inner: false,
})
}
struct BasicAdtInfo {
name: tt::Ident,
type_params: usize,
@ -261,7 +274,7 @@ mod tests {
use super::*;
fn expand_builtin_derive(s: &str, name: Name) -> String {
let def = find_builtin_derive(&name).unwrap();
let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
let fixture = format!(
r#"//- /main.rs crate:main deps:core
<|>
@ -283,7 +296,12 @@ mod tests {
let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
let loc = MacroCallLoc {
def,
def: MacroDefId {
krate: CrateId(0),
ast_id: None,
kind: MacroDefKind::BuiltInDerive(expander),
local_inner: false,
},
krate: CrateId(0),
kind: MacroCallKind::Attr(attr_id, name.to_string()),
};

View file

@ -69,13 +69,13 @@ pub fn find_builtin_macro(
match kind {
Either::Left(kind) => Some(MacroDefId {
krate: Some(krate),
krate,
ast_id: Some(ast_id),
kind: MacroDefKind::BuiltIn(kind),
local_inner: false,
}),
Either::Right(kind) => Some(MacroDefId {
krate: Some(krate),
krate,
ast_id: Some(ast_id),
kind: MacroDefKind::BuiltInEager(kind),
local_inner: false,
@ -534,7 +534,7 @@ mod tests {
Either::Left(expander) => {
// the first one should be a macro_rules
let def = MacroDefId {
krate: Some(CrateId(0)),
krate: CrateId(0),
ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))),
kind: MacroDefKind::BuiltIn(expander),
local_inner: false,
@ -555,7 +555,7 @@ mod tests {
Either::Right(expander) => {
// the first one should be a macro_rules
let def = MacroDefId {
krate: Some(krate),
krate,
ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_rules))),
kind: MacroDefKind::BuiltInEager(expander),
local_inner: false,

View file

@ -29,8 +29,8 @@ impl Hygiene {
MacroCallId::LazyMacro(id) => {
let loc = db.lookup_intern_macro(id);
match loc.def.kind {
MacroDefKind::Declarative => (loc.def.krate, loc.def.local_inner),
MacroDefKind::BuiltIn(_) => (loc.def.krate, false),
MacroDefKind::Declarative => (Some(loc.def.krate), loc.def.local_inner),
MacroDefKind::BuiltIn(_) => (Some(loc.def.krate), false),
MacroDefKind::BuiltInDerive(_) => (None, false),
MacroDefKind::BuiltInEager(_) => (None, false),
MacroDefKind::ProcMacro(_) => (None, false),

View file

@ -224,13 +224,7 @@ impl From<EagerMacroId> for MacroCallId {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroDefId {
// FIXME: krate and ast_id are currently optional because we don't have a
// definition location for built-in derives. There is one, though: the
// standard library defines them. The problem is that it uses the new
// `macro` syntax for this, which we don't support yet. As soon as we do
// (which will probably require touching this code), we can instead use
// that (and also remove the hacks for resolving built-in derives).
pub krate: Option<CrateId>,
pub krate: CrateId,
pub ast_id: Option<AstId<ast::Macro>>,
pub kind: MacroDefKind,