Skip to content

Commit 2c2bbe0

Browse files
committed
Treat Derive Macro specially.
1 parent 4bd2f94 commit 2c2bbe0

File tree

6 files changed

+87
-40
lines changed

6 files changed

+87
-40
lines changed

crates/hir-def/src/nameres/attr_resolution.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use base_db::CrateId;
44
use hir_expand::{
55
attrs::{Attr, AttrId, AttrInput},
6-
MacroCallId, MacroCallKind, MacroDefId,
6+
AstId, MacroCallId, MacroCallKind, MacroDefId,
77
};
88
use span::SyntaxContextId;
99
use syntax::{ast, SmolStr};
@@ -98,7 +98,20 @@ impl DefMap {
9898
false
9999
}
100100
}
101-
101+
pub(super) fn derive_attr_macro_as_call_id(
102+
db: &dyn DefDatabase,
103+
item_attr: &AstId<ast::Adt>,
104+
macro_attr: &Attr,
105+
krate: CrateId,
106+
def: MacroDefId,
107+
) -> MacroCallId {
108+
def.make_call(
109+
db.upcast(),
110+
krate,
111+
MacroCallKind::DeriveAttr { ast_id: *item_attr, invoc_attr_index: macro_attr.id },
112+
macro_attr.ctxt,
113+
)
114+
}
102115
pub(super) fn attr_macro_as_call_id(
103116
db: &dyn DefDatabase,
104117
item_attr: &AstIdWithPath<ast::Item>,

crates/hir-def/src/nameres/collector.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::item_tree::Mod;
1414
use crate::item_tree::ModKind;
1515
use crate::macro_call_as_call_id_with_eager;
1616

17+
use crate::nameres::attr_resolution::derive_attr_macro_as_call_id;
1718
use crate::nameres::mod_resolution::ModDir;
1819

1920
use crate::item_tree::ItemTree;
@@ -1258,9 +1259,7 @@ impl DefCollector<'_> {
12581259
Some(def) if def.is_attribute() => def,
12591260
_ => return Resolved::No,
12601261
};
1261-
// We will treat derive macros as an attribute as a reference for the input to derives
1262-
let call_id =
1263-
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
1262+
12641263
if let MacroDefId {
12651264
kind:
12661265
MacroDefKind::BuiltInAttr(
@@ -1289,8 +1288,16 @@ impl DefCollector<'_> {
12891288
return recollect_without(self);
12901289
}
12911290
};
1292-
let ast_id = ast_id.with_value(ast_adt_id);
12931291

1292+
let ast_id = ast_id.with_value(ast_adt_id);
1293+
// the call_id for the actual derive macro. This is used so all the derive proc macros can share a token tree
1294+
let call_id = derive_attr_macro_as_call_id(
1295+
self.db,
1296+
&ast_id,
1297+
attr,
1298+
self.def_map.krate,
1299+
def,
1300+
);
12941301
match attr.parse_path_comma_token_tree(self.db.upcast()) {
12951302
Some(derive_macros) => {
12961303
let mut len = 0;
@@ -1338,7 +1345,8 @@ impl DefCollector<'_> {
13381345

13391346
return recollect_without(self);
13401347
}
1341-
1348+
let call_id =
1349+
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
13421350
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
13431351
// due to duplicating functions into macro expansions
13441352
if matches!(

crates/hir-expand/src/cfg_process.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub(crate) fn process_cfg_attrs(
180180
db: &dyn ExpandDatabase,
181181
) -> Option<FxHashSet<SyntaxElement>> {
182182
// FIXME: #[cfg_eval] is not implemented. But it is not stable yet
183-
if !matches!(loc.kind, MacroCallKind::Derive { .. }) {
183+
if !matches!(loc.kind, MacroCallKind::Derive { .. } | MacroCallKind::DeriveAttr { .. }) {
184184
return None;
185185
}
186186
let mut remove = FxHashSet::default();

crates/hir-expand/src/db.rs

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use mbe::syntax_node_to_token_tree;
77
use rustc_hash::FxHashSet;
88
use span::{AstIdMap, Span, SyntaxContextData, SyntaxContextId};
99
use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T};
10-
use tracing::debug;
1110
use triomphe::Arc;
1211

1312
use crate::{
@@ -158,7 +157,8 @@ pub fn expand_speculative(
158157
SyntaxFixupUndoInfo::NONE,
159158
),
160159
MacroCallKind::Derive { derive_attr_index: index, .. }
161-
| MacroCallKind::Attr { invoc_attr_index: index, .. } => {
160+
| MacroCallKind::Attr { invoc_attr_index: index, .. }
161+
| MacroCallKind::DeriveAttr { invoc_attr_index: index, .. } => {
162162
let censor = if let MacroCallKind::Derive { .. } = loc.kind {
163163
censor_derive_input(index, &ast::Adt::cast(speculative_args.clone())?)
164164
} else {
@@ -347,31 +347,18 @@ type MacroArgResult = (Arc<tt::Subtree>, SyntaxFixupUndoInfo, Span);
347347
/// Other wise return the [macro_arg] for the macro_call_id.
348348
///
349349
/// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is
350-
///
351-
/// FIXME: Pick a better name
352-
fn smart_macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
353-
let loc = db.lookup_intern_macro_call(id);
350+
fn macro_arg_considering_derives(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
351+
let macro_call_kind = db.lookup_intern_macro_call(id).kind;
354352
// FIXME: We called lookup_intern_macro_call twice.
355-
match loc.kind {
353+
match macro_call_kind {
356354
// Get the macro arg for the derive macro
357-
MacroCallKind::Derive { derive_macro_id, .. } => {
358-
debug!(
359-
?loc,
360-
"{id:?} is a derive macro. Using the derive macro, id: {derive_macro_id:?}, attribute as the macro arg."
361-
);
362-
db.macro_arg(derive_macro_id)
363-
}
355+
MacroCallKind::Derive { derive_macro_id, .. } => db.macro_arg(derive_macro_id),
364356
// Normal macro arg
365357
_ => db.macro_arg(id),
366358
}
367359
}
368360

369-
fn macro_arg(
370-
db: &dyn ExpandDatabase,
371-
id: MacroCallId,
372-
// FIXME: consider the following by putting fixup info into eager call info args
373-
// ) -> ValueResult<Arc<(tt::Subtree, SyntaxFixupUndoInfo)>, Arc<Box<[SyntaxError]>>> {
374-
) -> MacroArgResult {
361+
fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
375362
let loc = db.lookup_intern_macro_call(id);
376363

377364
if let MacroCallLoc {
@@ -441,7 +428,9 @@ fn macro_arg(
441428
}
442429
return (Arc::new(tt), SyntaxFixupUndoInfo::NONE, span);
443430
}
444-
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
431+
// MacroCallKind::Derive should not be here. As we are getting the argument for the derive macro
432+
MacroCallKind::Derive { ast_id, derive_attr_index, .. }
433+
| MacroCallKind::DeriveAttr { ast_id, invoc_attr_index: derive_attr_index } => {
445434
let node = ast_id.to_ptr(db).to_node(&root);
446435
let censor_derive_input = censor_derive_input(derive_attr_index, &node);
447436
let item_node = node.into();
@@ -553,7 +542,7 @@ fn macro_expand(
553542
let (ExpandResult { value: tt, err }, span) = match loc.def.kind {
554543
MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id).map(CowArc::Arc),
555544
_ => {
556-
let (macro_arg, undo_info, span) = smart_macro_arg(db, macro_call_id);
545+
let (macro_arg, undo_info, span) = macro_arg_considering_derives(db, macro_call_id);
557546

558547
let arg = &*macro_arg;
559548
let res =
@@ -630,7 +619,7 @@ fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId<ast::Fn>) -> Span {
630619

631620
fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt::Subtree>> {
632621
let loc = db.lookup_intern_macro_call(id);
633-
let (macro_arg, undo_info, span) = smart_macro_arg(db, id);
622+
let (macro_arg, undo_info, span) = macro_arg_considering_derives(db, id);
634623

635624
let (expander, ast) = match loc.def.kind {
636625
MacroDefKind::ProcMacro(expander, _, ast) => (expander, ast),

crates/hir-expand/src/lib.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ pub enum MacroCallKind {
228228
/// We will resolve the same token tree for all derive macros in the same derive attribute.
229229
derive_macro_id: MacroCallId,
230230
},
231+
DeriveAttr {
232+
ast_id: AstId<ast::Adt>,
233+
invoc_attr_index: AttrId,
234+
},
231235
Attr {
232236
ast_id: AstId<ast::Item>,
233237
// FIXME: This shouldn't be here, we can derive this from `invoc_attr_index`
@@ -515,7 +519,8 @@ impl MacroCallLoc {
515519
MacroCallKind::FnLike { ast_id, .. } => {
516520
ast_id.with_value(ast_id.to_node(db).syntax().clone())
517521
}
518-
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
522+
MacroCallKind::Derive { ast_id, derive_attr_index, .. }
523+
| MacroCallKind::DeriveAttr { ast_id, invoc_attr_index: derive_attr_index } => {
519524
// FIXME: handle `cfg_attr`
520525
ast_id.with_value(ast_id.to_node(db)).map(|it| {
521526
collect_attrs(&it)
@@ -549,7 +554,7 @@ impl MacroCallLoc {
549554
fn expand_to(&self) -> ExpandTo {
550555
match self.kind {
551556
MacroCallKind::FnLike { expand_to, .. } => expand_to,
552-
MacroCallKind::Derive { .. } => ExpandTo::Items,
557+
MacroCallKind::Derive { .. } | MacroCallKind::DeriveAttr { .. } => ExpandTo::Items,
553558
MacroCallKind::Attr { .. } if self.def.is_attribute_derive() => ExpandTo::Items,
554559
MacroCallKind::Attr { .. } => {
555560
// FIXME(stmt_expr_attributes)
@@ -583,6 +588,7 @@ impl MacroCallKind {
583588
MacroCallKind::FnLike { .. } => "macro call",
584589
MacroCallKind::Derive { .. } => "derive macro",
585590
MacroCallKind::Attr { .. } => "attribute macro",
591+
MacroCallKind::DeriveAttr { .. } => "derive attribute",
586592
}
587593
}
588594

@@ -591,14 +597,16 @@ impl MacroCallKind {
591597
match *self {
592598
MacroCallKind::FnLike { ast_id: InFile { file_id, .. }, .. }
593599
| MacroCallKind::Derive { ast_id: InFile { file_id, .. }, .. }
600+
| MacroCallKind::DeriveAttr { ast_id: InFile { file_id, .. }, .. }
594601
| MacroCallKind::Attr { ast_id: InFile { file_id, .. }, .. } => file_id,
595602
}
596603
}
597604

598605
pub fn erased_ast_id(&self) -> ErasedFileAstId {
599606
match *self {
600607
MacroCallKind::FnLike { ast_id: InFile { value, .. }, .. } => value.erase(),
601-
MacroCallKind::Derive { ast_id: InFile { value, .. }, .. } => value.erase(),
608+
MacroCallKind::Derive { ast_id: InFile { value, .. }, .. }
609+
| MacroCallKind::DeriveAttr { ast_id: InFile { value, .. }, .. } => value.erase(),
602610
MacroCallKind::Attr { ast_id: InFile { value, .. }, .. } => value.erase(),
603611
}
604612
}
@@ -619,7 +627,9 @@ impl MacroCallKind {
619627

620628
let range = match kind {
621629
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_ptr(db).text_range(),
622-
MacroCallKind::Derive { ast_id, .. } => ast_id.to_ptr(db).text_range(),
630+
MacroCallKind::Derive { ast_id, .. } | MacroCallKind::DeriveAttr { ast_id, .. } => {
631+
ast_id.to_ptr(db).text_range()
632+
}
623633
MacroCallKind::Attr { ast_id, .. } => ast_id.to_ptr(db).text_range(),
624634
};
625635

@@ -665,6 +675,15 @@ impl MacroCallKind {
665675
.syntax()
666676
.text_range()
667677
}
678+
MacroCallKind::DeriveAttr { ast_id, invoc_attr_index } => {
679+
collect_attrs(&ast_id.to_node(db))
680+
.nth(invoc_attr_index.ast_index())
681+
.expect("missing attribute")
682+
.1
683+
.expect_left("attribute macro is a doc comment?")
684+
.syntax()
685+
.text_range()
686+
}
668687
};
669688

670689
FileRange { range, file_id }
@@ -675,7 +694,7 @@ impl MacroCallKind {
675694
MacroCallKind::FnLike { ast_id, .. } => {
676695
ast_id.to_in_file_node(db).map(|it| Some(it.token_tree()?.syntax().clone()))
677696
}
678-
MacroCallKind::Derive { ast_id, .. } => {
697+
MacroCallKind::Derive { ast_id, .. } | MacroCallKind::DeriveAttr { ast_id, .. } => {
679698
ast_id.to_in_file_node(db).syntax().cloned().map(Some)
680699
}
681700
MacroCallKind::Attr { ast_id, .. } => {

crates/hir/src/lib.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -972,8 +972,7 @@ fn precise_macro_call_location(
972972
MacroKind::ProcMacro,
973973
)
974974
}
975-
// TODO: derive_macro_id
976-
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, derive_macro_id } => {
975+
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => {
977976
let node = ast_id.to_node(db.upcast());
978977
// Compute the precise location of the macro name's token in the derive
979978
// list.
@@ -1023,6 +1022,26 @@ fn precise_macro_call_location(
10231022
MacroKind::Attr,
10241023
)
10251024
}
1025+
MacroCallKind::DeriveAttr { ast_id, invoc_attr_index } => {
1026+
let node = ast_id.to_node(db.upcast());
1027+
let attr = collect_attrs(&node)
1028+
.nth(invoc_attr_index.ast_index())
1029+
.and_then(|x| Either::left(x.1))
1030+
.unwrap_or_else(|| {
1031+
panic!("cannot find attribute #{}", invoc_attr_index.ast_index())
1032+
});
1033+
1034+
(
1035+
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
1036+
Some(attr.syntax().text_range()),
1037+
attr.path()
1038+
.and_then(|path| path.segment())
1039+
.and_then(|seg| seg.name_ref())
1040+
.as_ref()
1041+
.map(ToString::to_string),
1042+
MacroKind::Attr,
1043+
)
1044+
}
10261045
}
10271046
}
10281047

@@ -3710,8 +3729,7 @@ impl Impl {
37103729
let macro_file = src.file_id.macro_file()?;
37113730
let loc = macro_file.macro_call_id.lookup(db.upcast());
37123731
let (derive_attr, derive_index) = match loc.kind {
3713-
// TODO: derive_macro_id
3714-
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, derive_macro_id } => {
3732+
MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => {
37153733
let module_id = self.id.lookup(db.upcast()).container;
37163734
(
37173735
db.crate_def_map(module_id.krate())[module_id.local_id]

0 commit comments

Comments
 (0)