Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22383 from ChayimFriedman2/unimplemented-builtin
fix: Have a specific error for unimplemented builtin macros
Lukas Wirth 2 weeks ago
parent 746dab2 · parent 01725a4 · commit b231594
-rw-r--r--crates/hir-def/src/db.rs1
-rw-r--r--crates/hir-def/src/lib.rs1
-rw-r--r--crates/hir-def/src/nameres.rs1
-rw-r--r--crates/hir-def/src/nameres/collector.rs4
-rw-r--r--crates/hir-expand/src/db.rs13
-rw-r--r--crates/hir-expand/src/eager.rs3
-rw-r--r--crates/hir-expand/src/lib.rs21
-rw-r--r--crates/hir/src/lib.rs2
-rw-r--r--crates/ide-diagnostics/src/handlers/macro_error.rs17
9 files changed, 53 insertions, 10 deletions
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 6301eb7901..1776b7c84b 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -75,6 +75,7 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
MacroExpander::BuiltInAttr(it) => MacroDefKind::BuiltInAttr(in_file, it),
MacroExpander::BuiltInDerive(it) => MacroDefKind::BuiltInDerive(in_file, it),
MacroExpander::BuiltInEager(it) => MacroDefKind::BuiltInEager(in_file, it),
+ MacroExpander::UnimplementedBuiltIn => MacroDefKind::UnimplementedBuiltIn(in_file),
}
};
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 5959634555..a1bb82e7f2 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -442,6 +442,7 @@ pub enum MacroExpander {
BuiltInAttr(BuiltinAttrExpander),
BuiltInDerive(BuiltinDeriveExpander),
BuiltInEager(EagerExpander),
+ UnimplementedBuiltIn,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index 880130f6d2..0c7e7a3ca0 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -850,6 +850,7 @@ pub(crate) fn macro_styles_from_id(db: &dyn DefDatabase, macro_id: MacroId) -> M
MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroCallStyles::FN_LIKE,
MacroExpander::BuiltInAttr(_) => MacroCallStyles::ATTR,
MacroExpander::BuiltInDerive(_) => MacroCallStyles::DERIVE,
+ MacroExpander::UnimplementedBuiltIn => MacroCallStyles::all(), // Unknown.
}
}
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 5651d8e56d..a916cda730 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -2562,7 +2562,7 @@ impl ModCollector<'_, '_> {
.def_map
.diagnostics
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
- return;
+ MacroExpander::UnimplementedBuiltIn
}
}
} else {
@@ -2641,7 +2641,7 @@ impl ModCollector<'_, '_> {
.def_map
.diagnostics
.push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
- return;
+ MacroExpander::UnimplementedBuiltIn
}
} else {
// Case 2: normal `macro`
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index 878fae88ad..513115684f 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -43,6 +43,7 @@ pub enum TokenExpander<'db> {
BuiltInAttr(BuiltinAttrExpander),
/// `derive(Copy)` and such.
BuiltInDerive(BuiltinDeriveExpander),
+ UnimplementedBuiltIn,
/// The thing we love the most here in rust-analyzer -- procedural macros.
ProcMacro(CustomProcMacroExpander),
}
@@ -311,6 +312,7 @@ pub fn expand_speculative(
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
}
MacroDefKind::BuiltInAttr(_, it) => it.expand(db, actual_macro_call, &tt, span),
+ MacroDefKind::UnimplementedBuiltIn(_) => expand_unimplemented_builtin_macro(span),
};
let expand_to = loc.expand_to();
@@ -335,6 +337,13 @@ pub fn expand_speculative(
Some((node.syntax_node(), token))
}
+fn expand_unimplemented_builtin_macro(span: Span) -> ExpandResult<tt::TopSubtree> {
+ ExpandResult::new(
+ tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
+ ExpandError::other(span, "this built-in macro is not implemented"),
+ )
+}
+
#[salsa::tracked(lru = 1024, returns(ref))]
fn ast_id_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> AstIdMap {
AstIdMap::from_source(&db.parse_or_expand(file_id))
@@ -538,6 +547,7 @@ impl<'db> TokenExpander<'db> {
MacroDefKind::BuiltInDerive(_, expander) => TokenExpander::BuiltInDerive(expander),
MacroDefKind::BuiltInEager(_, expander) => TokenExpander::BuiltInEager(expander),
MacroDefKind::ProcMacro(_, expander, _) => TokenExpander::ProcMacro(expander),
+ MacroDefKind::UnimplementedBuiltIn(_) => TokenExpander::UnimplementedBuiltIn,
}
}
}
@@ -572,6 +582,9 @@ fn macro_expand<'db>(
MacroDefKind::BuiltInDerive(_, it) => {
it.expand(db, macro_call_id, arg, span).map_err(Into::into).zip_val(None)
}
+ MacroDefKind::UnimplementedBuiltIn(_) => {
+ expand_unimplemented_builtin_macro(span).zip_val(None)
+ }
MacroDefKind::BuiltInEager(_, it) => {
// This might look a bit odd, but we do not expand the inputs to eager macros here.
// Eager macros inputs are expanded, well, eagerly when we collect the macro calls.
diff --git a/crates/hir-expand/src/eager.rs b/crates/hir-expand/src/eager.rs
index a19f58709b..f8a560834a 100644
--- a/crates/hir-expand/src/eager.rs
+++ b/crates/hir-expand/src/eager.rs
@@ -246,7 +246,8 @@ fn eager_macro_recur(
| MacroDefKind::BuiltIn(..)
| MacroDefKind::BuiltInAttr(..)
| MacroDefKind::BuiltInDerive(..)
- | MacroDefKind::ProcMacro(..) => {
+ | MacroDefKind::ProcMacro(..)
+ | MacroDefKind::UnimplementedBuiltIn(..) => {
let ExpandResult { value: (parse, tm), err } = lazy_expand(
db,
&def,
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index c98d072784..9c5714be2d 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -249,6 +249,7 @@ pub enum MacroDefKind {
BuiltInAttr(AstId<ast::Macro>, BuiltinAttrExpander),
BuiltInDerive(AstId<ast::Macro>, BuiltinDeriveExpander),
BuiltInEager(AstId<ast::Macro>, EagerExpander),
+ UnimplementedBuiltIn(AstId<ast::Macro>),
ProcMacro(AstId<ast::Fn>, CustomProcMacroExpander, ProcMacroKind),
}
@@ -265,7 +266,8 @@ impl MacroDefKind {
| MacroDefKind::BuiltInAttr(id, _)
| MacroDefKind::BuiltInDerive(id, _)
| MacroDefKind::BuiltInEager(id, _)
- | MacroDefKind::Declarative(id, ..) => id.erase(),
+ | MacroDefKind::Declarative(id, ..)
+ | MacroDefKind::UnimplementedBuiltIn(id) => id.erase(),
}
}
}
@@ -500,6 +502,7 @@ impl MacroCallId {
MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) => MacroKind::Attr,
MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang) => MacroKind::ProcMacro,
MacroDefKind::BuiltInAttr(..) => MacroKind::AttrBuiltIn,
+ MacroDefKind::UnimplementedBuiltIn(..) => MacroKind::Declarative,
}
}
@@ -551,7 +554,8 @@ impl MacroDefId {
| MacroDefKind::BuiltIn(id, _)
| MacroDefKind::BuiltInAttr(id, _)
| MacroDefKind::BuiltInDerive(id, _)
- | MacroDefKind::BuiltInEager(id, _) => {
+ | MacroDefKind::BuiltInEager(id, _)
+ | MacroDefKind::UnimplementedBuiltIn(id) => {
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
}
MacroDefKind::ProcMacro(id, _, _) => {
@@ -567,7 +571,8 @@ impl MacroDefId {
| MacroDefKind::BuiltIn(id, _)
| MacroDefKind::BuiltInAttr(id, _)
| MacroDefKind::BuiltInDerive(id, _)
- | MacroDefKind::BuiltInEager(id, _) => Either::Left(id),
+ | MacroDefKind::BuiltInEager(id, _)
+ | MacroDefKind::UnimplementedBuiltIn(id) => Either::Left(id),
}
}
@@ -577,9 +582,9 @@ impl MacroDefId {
pub fn is_attribute(&self) -> bool {
match self.kind {
- MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) => {
- true
- }
+ MacroDefKind::BuiltInAttr(..)
+ | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr)
+ | MacroDefKind::UnimplementedBuiltIn(_) => true,
MacroDefKind::Declarative(_, styles) => styles.contains(MacroCallStyles::ATTR),
_ => false,
}
@@ -588,7 +593,8 @@ impl MacroDefId {
pub fn is_derive(&self) -> bool {
match self.kind {
MacroDefKind::BuiltInDerive(..)
- | MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) => true,
+ | MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive)
+ | MacroDefKind::UnimplementedBuiltIn(_) => true,
MacroDefKind::Declarative(_, styles) => styles.contains(MacroCallStyles::DERIVE),
_ => false,
}
@@ -601,6 +607,7 @@ impl MacroDefId {
| MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang)
| MacroDefKind::BuiltInEager(..)
| MacroDefKind::Declarative(..)
+ | MacroDefKind::UnimplementedBuiltIn(_)
)
}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9f94243062..768ffd5697 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3612,6 +3612,7 @@ impl Macro {
}
MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
+ MacroExpander::UnimplementedBuiltIn => MacroKind::Declarative,
},
MacroId::MacroRulesId(it) => match it.lookup(db).expander {
MacroExpander::Declarative { .. } => MacroKind::Declarative,
@@ -3620,6 +3621,7 @@ impl Macro {
}
MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
+ MacroExpander::UnimplementedBuiltIn => MacroKind::Declarative,
},
MacroId::ProcMacroId(it) => match it.lookup(db).kind {
ProcMacroKind::CustomDerive => MacroKind::Derive,
diff --git a/crates/ide-diagnostics/src/handlers/macro_error.rs b/crates/ide-diagnostics/src/handlers/macro_error.rs
index b6571e02ef..7acbcad22c 100644
--- a/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -327,4 +327,21 @@ fn it_works() {
"#,
);
}
+
+ #[test]
+ fn unimplemented_builtin_macro() {
+ check_diagnostics(
+ r#"
+#[rustc_builtin_macro]
+macro_rules! unimplemented_builtin_macro {
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: unimplemented built-in macro
+ () => {};
+}
+
+ #[unimplemented_builtin_macro]
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this built-in macro is not implemented
+struct Foo;
+ "#,
+ );
+ }
}