Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir_expand/src/lib.rs61
-rw-r--r--crates/proc_macro_srv/src/abis/abi_1_56/mod.rs6
-rw-r--r--crates/proc_macro_srv/src/abis/abi_1_58/mod.rs6
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs13
-rw-r--r--crates/syntax/src/ast/node_ext.rs1
-rw-r--r--crates/syntax/src/tests/sourcegen_ast.rs4
6 files changed, 71 insertions, 20 deletions
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 5f190b8727..5e49d3f6af 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -350,6 +350,53 @@ impl MacroCallKind {
}
}
+ /// Returns the original file range that best describes the location of this macro call.
+ ///
+ /// Here we try to roughly match what rustc does to improve diagnostics: fn-like macros
+ /// get the whole `ast::MacroCall`, attribute macros get the attribute's range, and derives
+ /// get only the specific derive that is being referred to.
+ pub fn original_call_range(self, db: &dyn db::AstDatabase) -> FileRange {
+ let mut kind = self;
+ loop {
+ match kind.file_id().0 {
+ HirFileIdRepr::MacroFile(file) => {
+ kind = db.lookup_intern_macro_call(file.macro_call_id).kind;
+ }
+ _ => break,
+ }
+ }
+
+ // `call_id` is now the outermost macro call, so its location is in a real file.
+ let file_id = match kind.file_id().0 {
+ HirFileIdRepr::FileId(it) => it,
+ HirFileIdRepr::MacroFile(_) => unreachable!("encountered unexpected macro file"),
+ };
+ let range = match kind {
+ MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
+ MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
+ // FIXME: should be the range of the macro name, not the whole derive
+ ast_id
+ .to_node(db)
+ .doc_comments_and_attrs()
+ .nth(derive_attr_index as usize)
+ .expect("missing derive")
+ .expect_right("derive is a doc comment?")
+ .syntax()
+ .text_range()
+ }
+ MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => ast_id
+ .to_node(db)
+ .doc_comments_and_attrs()
+ .nth(invoc_attr_index as usize)
+ .expect("missing attribute")
+ .expect_right("attribute macro is a doc comment?")
+ .syntax()
+ .text_range(),
+ };
+
+ FileRange { range, file_id }
+ }
+
fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> {
match self {
MacroCallKind::FnLike { ast_id, .. } => {
@@ -623,15 +670,13 @@ impl<'a> InFile<&'a SyntaxNode> {
}
// Fall back to whole macro call.
- let mut node = self.cloned();
- while let Some(call_node) = node.file_id.call_node(db) {
- node = call_node;
+ match self.file_id.0 {
+ HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
+ HirFileIdRepr::MacroFile(mac_file) => {
+ let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
+ loc.kind.original_call_range(db)
+ }
}
-
- let orig_file = node.file_id.original_file(db);
- assert_eq!(node.file_id, orig_file.into());
-
- FileRange { file_id: orig_file, range: node.value.text_range() }
}
/// Attempts to map the syntax node back up its macro calls.
diff --git a/crates/proc_macro_srv/src/abis/abi_1_56/mod.rs b/crates/proc_macro_srv/src/abis/abi_1_56/mod.rs
index 96b71d3f21..ee1c2d4553 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_56/mod.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_56/mod.rs
@@ -51,7 +51,7 @@ impl Abi {
&proc_macro::bridge::server::SameThread,
rustc_server::Rustc::default(),
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
@@ -62,7 +62,7 @@ impl Abi {
&proc_macro::bridge::server::SameThread,
rustc_server::Rustc::default(),
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
@@ -74,7 +74,7 @@ impl Abi {
rustc_server::Rustc::default(),
parsed_attributes,
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
diff --git a/crates/proc_macro_srv/src/abis/abi_1_58/mod.rs b/crates/proc_macro_srv/src/abis/abi_1_58/mod.rs
index 4421382006..dd3fd8b642 100644
--- a/crates/proc_macro_srv/src/abis/abi_1_58/mod.rs
+++ b/crates/proc_macro_srv/src/abis/abi_1_58/mod.rs
@@ -51,7 +51,7 @@ impl Abi {
&proc_macro::bridge::server::SameThread,
rustc_server::Rustc::default(),
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
@@ -62,7 +62,7 @@ impl Abi {
&proc_macro::bridge::server::SameThread,
rustc_server::Rustc::default(),
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
@@ -74,7 +74,7 @@ impl Abi {
rustc_server::Rustc::default(),
parsed_attributes,
parsed_body,
- false,
+ true,
);
return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
}
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 8e55afb949..09c5af210f 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -162,6 +162,7 @@ pub struct MacroCall {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasAttrs for MacroCall {}
+impl ast::HasDocComments for MacroCall {}
impl MacroCall {
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
@@ -259,6 +260,7 @@ pub struct ExternBlock {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasAttrs for ExternBlock {}
+impl ast::HasDocComments for ExternBlock {}
impl ExternBlock {
pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
pub fn extern_item_list(&self) -> Option<ExternItemList> { support::child(&self.syntax) }
@@ -270,6 +272,7 @@ pub struct ExternCrate {
}
impl ast::HasAttrs for ExternCrate {}
impl ast::HasVisibility for ExternCrate {}
+impl ast::HasDocComments for ExternCrate {}
impl ExternCrate {
pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
@@ -1543,6 +1546,7 @@ pub enum Item {
Use(Use),
}
impl ast::HasAttrs for Item {}
+impl ast::HasDocComments for Item {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Stmt {
@@ -1597,6 +1601,7 @@ pub enum AssocItem {
TypeAlias(TypeAlias),
}
impl ast::HasAttrs for AssocItem {}
+impl ast::HasDocComments for AssocItem {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ExternItem {
@@ -1606,6 +1611,7 @@ pub enum ExternItem {
TypeAlias(TypeAlias),
}
impl ast::HasAttrs for ExternItem {}
+impl ast::HasDocComments for ExternItem {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum GenericParam {
@@ -3902,10 +3908,9 @@ impl AnyHasDocComments {
impl AstNode for AnyHasDocComments {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
- SOURCE_FILE | CONST | ENUM | FN | IMPL | MACRO_RULES | MACRO_DEF | MODULE | STATIC
- | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => {
- true
- }
+ MACRO_CALL | SOURCE_FILE | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL
+ | MACRO_RULES | MACRO_DEF | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION
+ | USE | RECORD_FIELD | TUPLE_FIELD | VARIANT => true,
_ => false,
}
}
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 470e9a04b3..705aa5edac 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -772,7 +772,6 @@ impl ast::HasLoopBody for ast::ForExpr {
}
impl ast::HasAttrs for ast::AnyHasDocComments {}
-impl ast::HasDocComments for ast::Item {}
impl From<ast::Adt> for ast::Item {
fn from(it: ast::Adt) -> Self {
diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs
index ac928402f3..4a608da9ff 100644
--- a/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -793,9 +793,11 @@ fn extract_struct_traits(ast: &mut AstSrc) {
"Const",
"TypeAlias",
"Impl",
+ "ExternBlock",
+ "ExternCrate",
+ "MacroCall",
"MacroRules",
"MacroDef",
- "Macro",
"Use",
];