diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-17 07:20:28 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-17 07:20:28 +0000 |
commit | 6fcb5d772f16af0d1f62dad55fbde75072fb9e89 (patch) | |
tree | e4ddd896f9ca8ca1f99c346a49104b04bc4ca04c /crates/hir_def/src/data.rs | |
parent | 83e6940efb42675226adb8d2856c095b8dce36c5 (diff) | |
parent | a79b5673e8f5d1f8d569bc7c984a293a972a7bb0 (diff) |
Merge #8048
8048: Fix missing unresolved macro diagnostic in function body r=edwin0cheng a=brandondong
This was an issue I found while working on https://github.com/rust-analyzer/rust-analyzer/pull/7970.
**Reproduction:**
1. Call a non-existent macro in a function body.
```
fn main() {
foo!();
}
```
2. No diagnostics are raised. An unresolved-macro-call diagnostic is expected.
3. If the macro call is instead outside of the function body, this works as expected.
I believe this worked previously and regressed in https://github.com/rust-analyzer/rust-analyzer/pull/7805.
**Behavior prior to https://github.com/rust-analyzer/rust-analyzer/pull/7805:**
- The unresolved-macro-call diagnostic did not exist. Instead, a macro-error diagnostic would be raised with the text "could not resolve macro [path]".
- This was implemented by adding an error to the error sink (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8L657).
- The error was propagated through https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body.rs#L123 eventually reaching https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body/lower.rs#L569.
**Behavior after:**
- Instead of writing to the error sink, an UnresolvedMacro error is now returned (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8R631).
- The parent caller throws away the error as its function signature is `Option<MacroCallId>` (https://github.com/rust-analyzer/rust-analyzer/pull/7805/files#diff-50a326c5ae465bd9b31ee4310186380aa06e4fa1f6b41dbc0aed5bcc656a3cb8R604).
- We instead now reach the warn condition (https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body.rs#L124) and no diagnostics are created in https://github.com/rust-analyzer/rust-analyzer/blob/1a82af3527e476d52410ff4dfd2fb4c57466abcb/crates/hir_def/src/body/lower.rs#L575.
**Fix:**
- Make sure to propagate the UnresolvedMacro error. Report the error using the new unresolved-macro-call diagnostic.
Co-authored-by: Brandon <[email protected]>
Diffstat (limited to 'crates/hir_def/src/data.rs')
-rw-r--r-- | crates/hir_def/src/data.rs | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 74a2194e5..1a27f7bf2 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -267,23 +267,26 @@ fn collect_items( | |||
267 | let ast_id_map = db.ast_id_map(file_id); | 267 | let ast_id_map = db.ast_id_map(file_id); |
268 | let root = db.parse_or_expand(file_id).unwrap(); | 268 | let root = db.parse_or_expand(file_id).unwrap(); |
269 | let call = ast_id_map.get(call.ast_id).to_node(&root); | 269 | let call = ast_id_map.get(call.ast_id).to_node(&root); |
270 | 270 | let res = expander.enter_expand(db, call); | |
271 | if let Some((mark, mac)) = expander.enter_expand(db, call).value { | 271 | |
272 | let src: InFile<ast::MacroItems> = expander.to_source(mac); | 272 | if let Ok(res) = res { |
273 | let item_tree = db.item_tree(src.file_id); | 273 | if let Some((mark, mac)) = res.value { |
274 | let iter = | 274 | let src: InFile<ast::MacroItems> = expander.to_source(mac); |
275 | item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); | 275 | let item_tree = db.item_tree(src.file_id); |
276 | items.extend(collect_items( | 276 | let iter = |
277 | db, | 277 | item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); |
278 | module, | 278 | items.extend(collect_items( |
279 | expander, | 279 | db, |
280 | iter, | 280 | module, |
281 | src.file_id, | 281 | expander, |
282 | container, | 282 | iter, |
283 | limit - 1, | 283 | src.file_id, |
284 | )); | 284 | container, |
285 | 285 | limit - 1, | |
286 | expander.exit(db, mark); | 286 | )); |
287 | |||
288 | expander.exit(db, mark); | ||
289 | } | ||
287 | } | 290 | } |
288 | } | 291 | } |
289 | } | 292 | } |