Skip to content

Commit

Permalink
Pass calling span through to builtin macro expansions
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Dec 1, 2023
1 parent f48fa0c commit 9ca83b8
Show file tree
Hide file tree
Showing 26 changed files with 573 additions and 446 deletions.
2 changes: 1 addition & 1 deletion crates/hir-def/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ impl<'a> AssocItemCollector<'a> {
self.module_id.local_id,
MacroCallKind::Attr {
ast_id,
attr_args: Arc::new(tt::Subtree::empty()),
attr_args: None,
invoc_attr_index: attr.id,
},
attr.path().clone(),
Expand Down
8 changes: 4 additions & 4 deletions crates/hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,19 +1351,19 @@ fn attr_macro_as_call_id(
let arg = match macro_attr.input.as_deref() {
Some(AttrInput::TokenTree(tt)) => {
let mut tt = tt.as_ref().clone();
tt.delimiter = tt::Delimiter::UNSPECIFIED;
tt
tt.delimiter = tt::Delimiter::DUMMY_INVISIBLE;
Some(tt)
}

_ => tt::Subtree::empty(),
_ => None,
};

def.as_lazy_macro(
db.upcast(),
krate,
MacroCallKind::Attr {
ast_id: item_attr.ast_id,
attr_args: Arc::new(arg),
attr_args: arg.map(Arc::new),
invoc_attr_index: macro_attr.id,
},
macro_attr.ctxt,
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/macro_expansion_tests/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ macro_rules! identity {
}
fn main(foo: ()) {
builtin#FileId(0):[email protected]\0# ##FileId(0):[email protected]\0#format_args#FileId(0):[email protected]\0# (#FileId(0):[email protected]\0#"{} {} {}"#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# format_args#FileId(0):[email protected]\0#!#FileId(0):[email protected]\0#(#FileId(0):[email protected]\0#"{}"#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# 0#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# foo#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# identity#FileId(0):[email protected]\0#!#FileId(0):[email protected]\0#(#FileId(0):[email protected]\0#10#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# "bar"#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#
builtin#FileId(0):[email protected]\3# ##FileId(0):[email protected]\3#format_args#FileId(0):[email protected]\3# (#FileId(0):[email protected]\0#"{} {} {}"#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# format_args#FileId(0):[email protected]\0#!#FileId(0):[email protected]\0#(#FileId(0):[email protected]\0#"{}"#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# 0#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# foo#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# identity#FileId(0):[email protected]\0#!#FileId(0):[email protected]\0#(#FileId(0):[email protected]\0#10#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#,#FileId(0):[email protected]\0# "bar"#FileId(0):[email protected]\0#)#FileId(0):[email protected]\0#
}
"##]],
Expand Down
28 changes: 24 additions & 4 deletions crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use std::{cmp::Ordering, iter, mem};

use ::tt::Span;
use base_db::{span::SyntaxContextId, CrateId, Dependency, Edition, FileId};
use cfg::{CfgExpr, CfgOptions};
use either::Either;
Expand Down Expand Up @@ -85,7 +84,17 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
.enumerate()
.map(|(idx, it)| {
// FIXME: a hacky way to create a Name from string.
let name = tt::Ident { text: it.name.clone(), span: tt::SpanData::DUMMY };
let name = tt::Ident {
text: it.name.clone(),
span: tt::SpanData {
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
anchor: base_db::span::SpanAnchor {
file_id: FileId::BOGUS,
ast_id: base_db::span::ROOT_ERASED_FILE_AST_ID,
},
ctx: SyntaxContextId::ROOT,
},
};
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
})
.collect())
Expand Down Expand Up @@ -476,7 +485,7 @@ impl DefCollector<'_> {
directive.module_id,
MacroCallKind::Attr {
ast_id: ast_id.ast_id,
attr_args: Arc::new(tt::Subtree::empty()),
attr_args: None,
invoc_attr_index: attr.id,
},
attr.path().clone(),
Expand Down Expand Up @@ -2079,7 +2088,18 @@ impl ModCollector<'_, '_> {
let name = match attrs.by_key("rustc_builtin_macro").string_value() {
Some(it) => {
// FIXME: a hacky way to create a Name from string.
name = tt::Ident { text: it.clone(), span: tt::SpanData::DUMMY }.as_name();
name = tt::Ident {
text: it.clone(),
span: tt::SpanData {
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
anchor: base_db::span::SpanAnchor {
file_id: FileId::BOGUS,
ast_id: base_db::span::ROOT_ERASED_FILE_AST_ID,
},
ctx: SyntaxContextId::ROOT,
},
}
.as_name();
&name
}
None => {
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-expand/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl RawAttrs {
let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(
|(idx, attr)| {
let tree = Subtree {
delimiter: tt::Delimiter::unspecified(),
delimiter: tt::Delimiter::dummy_invisible(),
token_trees: attr.to_vec(),
};
Attr::from_tt(db, &tree, index.with_cfg_attr(idx))
Expand Down Expand Up @@ -296,7 +296,7 @@ impl Attr {
// FIXME: This is necessarily a hack. It'd be nice if we could avoid allocation
// here or maybe just parse a mod path from a token tree directly
let subtree = tt::Subtree {
delimiter: tt::Delimiter::unspecified(),
delimiter: tt::Delimiter::dummy_invisible(),
token_trees: tts.to_vec(),
};
let (parse, span_map) =
Expand Down
30 changes: 22 additions & 8 deletions crates/hir-expand/src/builtin_attr_macro.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
//! Builtin attributes.
use ::tt::Span;
use base_db::{
span::{SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
FileId,
};
use syntax::{TextRange, TextSize};

use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallId, MacroCallKind};

macro_rules! register_builtin {
( $(($name:ident, $variant:ident) => $expand:ident),* ) => {
($expand_fn:ident: $(($name:ident, $variant:ident) => $expand:ident),* ) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinAttrExpander {
$($variant),*
}

impl BuiltinAttrExpander {
pub fn expand(
pub fn $expand_fn(
&self,
db: &dyn ExpandDatabase,
id: MacroCallId,
Expand Down Expand Up @@ -47,7 +51,7 @@ impl BuiltinAttrExpander {
}
}

register_builtin! {
register_builtin! { expand:
(bench, Bench) => dummy_attr_expand,
(cfg_accessible, CfgAccessible) => dummy_attr_expand,
(cfg_eval, CfgEval) => dummy_attr_expand,
Expand Down Expand Up @@ -99,21 +103,31 @@ fn derive_attr_expand(
) -> ExpandResult<tt::Subtree> {
let loc = db.lookup_intern_macro_call(id);
let derives = match &loc.kind {
MacroCallKind::Attr { attr_args, .. } if loc.def.is_attribute_derive() => attr_args,
_ => return ExpandResult::ok(tt::Subtree::empty()),
MacroCallKind::Attr { attr_args: Some(attr_args), .. } if loc.def.is_attribute_derive() => {
attr_args
}
_ => return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan::DUMMY)),
};
pseudo_derive_attr_expansion(tt, derives)
pseudo_derive_attr_expansion(tt, derives, loc.call_site)
}

pub fn pseudo_derive_attr_expansion(
tt: &tt::Subtree,
args: &tt::Subtree,
call_site: SyntaxContextId,
) -> ExpandResult<tt::Subtree> {
let mk_leaf = |char| {
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
char,
spacing: tt::Spacing::Alone,
span: tt::SpanData::DUMMY,
span: tt::SpanData {
range: TextRange::empty(TextSize::new(0)),
anchor: base_db::span::SpanAnchor {
file_id: FileId::BOGUS,
ast_id: ROOT_ERASED_FILE_AST_ID,
},
ctx: call_site,
},
}))
};

Expand Down
Loading

0 comments on commit 9ca83b8

Please sign in to comment.