Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 14558af

Browse files
committed
Auto merge of rust-lang#16834 - Veykril:macarons, r=Veykril
feat: Support macro calls in eager macros for IDE features Basically hovering `concat` and `env` in `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` now works and highlights as expected. This also fixes a few bugs/problems to make it work. Prior we set the call site span to the entire macro call which is kind of wrong, typing inside the call would invalidate the span causing us to leak `MacroCallLoc`s whenever that happened. The same happened for attributes both of which now define their path as the call site.
2 parents 6fc3a3e + d085ade commit 14558af

File tree

26 files changed

+456
-262
lines changed

26 files changed

+456
-262
lines changed

crates/hir-def/src/data/adt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ impl StructData {
191191
let krate = loc.container.krate;
192192
let item_tree = loc.id.item_tree(db);
193193
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
194-
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
194+
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
195195

196-
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
196+
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
197197

198198
let mut flags = StructFlags::NO_FLAGS;
199199
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
@@ -248,9 +248,9 @@ impl StructData {
248248
let krate = loc.container.krate;
249249
let item_tree = loc.id.item_tree(db);
250250
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
251-
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
251+
let cfg_options = db.crate_graph()[krate].cfg_options.clone();
252252

253-
let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
253+
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
254254
let mut flags = StructFlags::NO_FLAGS;
255255
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
256256
flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL;

crates/hir-def/src/db.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,10 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
309309
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
310310
local_inner: false,
311311
allow_internal_unsafe: loc.allow_internal_unsafe,
312-
span: db
313-
.span_map(loc.id.file_id())
314-
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
312+
span: makro.def_site,
315313
edition: loc.edition,
316314
}
317315
}
318-
319316
MacroId::MacroRulesId(it) => {
320317
let loc: MacroRulesLoc = it.lookup(db);
321318

@@ -328,9 +325,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
328325
allow_internal_unsafe: loc
329326
.flags
330327
.contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE),
331-
span: db
332-
.span_map(loc.id.file_id())
333-
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
328+
span: makro.def_site,
334329
edition: loc.edition,
335330
}
336331
}
@@ -348,6 +343,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
348343
),
349344
local_inner: false,
350345
allow_internal_unsafe: false,
346+
// FIXME: This is wrong, this should point to the name
351347
span: db
352348
.span_map(loc.id.file_id())
353349
.span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),

crates/hir-def/src/item_tree.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,6 @@ pub struct MacroCall {
790790
pub path: Interned<ModPath>,
791791
pub ast_id: FileAstId<ast::MacroCall>,
792792
pub expand_to: ExpandTo,
793-
// FIXME: We need to move this out. It invalidates the item tree when typing inside the macro call.
794793
pub call_site: Span,
795794
}
796795

@@ -799,6 +798,7 @@ pub struct MacroRules {
799798
/// The name of the declared macro.
800799
pub name: Name,
801800
pub ast_id: FileAstId<ast::MacroRules>,
801+
pub def_site: Span,
802802
}
803803

804804
/// "Macros 2.0" macro definition.
@@ -807,6 +807,7 @@ pub struct Macro2 {
807807
pub name: Name,
808808
pub visibility: RawVisibilityId,
809809
pub ast_id: FileAstId<ast::MacroDef>,
810+
pub def_site: Span,
810811
}
811812

812813
impl Use {

crates/hir-def/src/item_tree/lower.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -560,35 +560,34 @@ impl<'a> Ctx<'a> {
560560

561561
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
562562
let span_map = self.span_map();
563-
let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, &mut |range| {
563+
let path = m.path()?;
564+
let range = path.syntax().text_range();
565+
let path = Interned::new(ModPath::from_src(self.db.upcast(), path, &mut |range| {
564566
span_map.span_for_range(range).ctx
565567
})?);
566568
let ast_id = self.source_ast_id_map.ast_id(m);
567569
let expand_to = hir_expand::ExpandTo::from_call_site(m);
568-
let res = MacroCall {
569-
path,
570-
ast_id,
571-
expand_to,
572-
call_site: span_map.span_for_range(m.syntax().text_range()),
573-
};
570+
let res = MacroCall { path, ast_id, expand_to, call_site: span_map.span_for_range(range) };
574571
Some(id(self.data().macro_calls.alloc(res)))
575572
}
576573

577574
fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
578-
let name = m.name().map(|it| it.as_name())?;
575+
let name = m.name()?;
576+
let def_site = self.span_map().span_for_range(name.syntax().text_range());
579577
let ast_id = self.source_ast_id_map.ast_id(m);
580578

581-
let res = MacroRules { name, ast_id };
579+
let res = MacroRules { name: name.as_name(), ast_id, def_site };
582580
Some(id(self.data().macro_rules.alloc(res)))
583581
}
584582

585583
fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<Macro2>> {
586-
let name = m.name().map(|it| it.as_name())?;
584+
let name = m.name()?;
585+
let def_site = self.span_map().span_for_range(name.syntax().text_range());
587586

588587
let ast_id = self.source_ast_id_map.ast_id(m);
589588
let visibility = self.lower_visibility(m);
590589

591-
let res = Macro2 { name, ast_id, visibility };
590+
let res = Macro2 { name: name.as_name(), ast_id, visibility, def_site };
592591
Some(id(self.data().macro_defs.alloc(res)))
593592
}
594593

crates/hir-def/src/item_tree/pretty.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,23 @@ impl Printer<'_> {
498498
wln!(self, "{}!(...);", path.display(self.db.upcast()));
499499
}
500500
ModItem::MacroRules(it) => {
501-
let MacroRules { name, ast_id } = &self.tree[it];
502-
self.print_ast_id(ast_id.erase());
501+
let MacroRules { name, ast_id, def_site } = &self.tree[it];
502+
let _ = writeln!(
503+
self,
504+
"// AstId: {:?}, Span: {}",
505+
ast_id.erase().into_raw(),
506+
def_site,
507+
);
503508
wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db.upcast()));
504509
}
505510
ModItem::Macro2(it) => {
506-
let Macro2 { name, visibility, ast_id } = &self.tree[it];
507-
self.print_ast_id(ast_id.erase());
511+
let Macro2 { name, visibility, ast_id, def_site } = &self.tree[it];
512+
let _ = writeln!(
513+
self,
514+
"// AstId: {:?}, Span: {}",
515+
ast_id.erase().into_raw(),
516+
def_site,
517+
);
508518
self.print_visibility(*visibility);
509519
wln!(self, "macro {} {{ ... }}", name.display(self.db.upcast()));
510520
}

crates/hir-def/src/item_tree/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,13 @@ pub macro m2() {}
272272
m!();
273273
"#,
274274
expect![[r#"
275-
// AstId: 1
275+
// AstId: 1, Span: 0:[email protected]#0
276276
macro_rules! m { ... }
277277
278-
// AstId: 2
278+
// AstId: 2, Span: 0:[email protected]#0
279279
pub macro m2 { ... }
280280
281-
// AstId: 3, Span: 0:3@0..5#0, ExpandTo: Items
281+
// AstId: 3, Span: 0:3@0..1#0, ExpandTo: Items
282282
m!(...);
283283
"#]],
284284
);

crates/hir-def/src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,17 +1342,18 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
13421342
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
13431343
let span_map = db.span_map(self.file_id);
13441344
let path = self.value.path().and_then(|path| {
1345-
path::ModPath::from_src(db, path, &mut |range| {
1345+
let range = path.syntax().text_range();
1346+
let mod_path = path::ModPath::from_src(db, path, &mut |range| {
13461347
span_map.as_ref().span_for_range(range).ctx
1347-
})
1348+
})?;
1349+
let call_site = span_map.span_for_range(range);
1350+
Some((call_site, mod_path))
13481351
});
13491352

1350-
let Some(path) = path else {
1353+
let Some((call_site, path)) = path else {
13511354
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
13521355
};
13531356

1354-
let call_site = span_map.span_for_range(self.value.syntax().text_range());
1355-
13561357
macro_call_as_call_id_with_eager(
13571358
db,
13581359
&AstIdWithPath::new(ast_id.file_id, ast_id.value, path),

crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ fn main(foo: ()) {
171171
}
172172
173173
fn main(foo: ()) {
174-
/* error: unresolved macro unresolved */"helloworld!"#0:3@207..323#2#;
174+
/* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#0#;
175175
}
176176
}
177177

crates/hir-expand/src/attrs.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,12 @@ impl Attr {
201201
span_map: SpanMapRef<'_>,
202202
id: AttrId,
203203
) -> Option<Attr> {
204-
let path = Interned::new(ModPath::from_src(db, ast.path()?, &mut |range| {
204+
let path = ast.path()?;
205+
let range = path.syntax().text_range();
206+
let path = Interned::new(ModPath::from_src(db, path, &mut |range| {
205207
span_map.span_for_range(range).ctx
206208
})?);
207-
let span = span_map.span_for_range(ast.syntax().text_range());
209+
let span = span_map.span_for_range(range);
208210
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
209211
let value = match lit.kind() {
210212
ast::LiteralKind::String(string) => string.value()?.into(),

0 commit comments

Comments
 (0)