about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-15 16:06:59 +0000
committerbors <bors@rust-lang.org>2022-08-15 16:06:59 +0000
commit3903243192d2bd6c38b43d12ffa9d2fa1601c2ec (patch)
tree0ed3c05dd5f24168b63ef5e048ea91bcfcc18e13
parent3561433ef2ee6eff86b99be4d9e59114c7f0f875 (diff)
parent8c60813096fca9ce5b81bdb22894ca1e1240fdb5 (diff)
downloadrust-3903243192d2bd6c38b43d12ffa9d2fa1601c2ec.tar.gz
rust-3903243192d2bd6c38b43d12ffa9d2fa1601c2ec.zip
Auto merge of #13027 - jonas-schievink:fix-mismatch-with-trailing-empty-macro, r=jonas-schievink
fix: Fix incorrect type mismatch with `cfg_if!` and other macros in expression position

Fixes https://github.com/rust-lang/rust-analyzer/issues/12940

This is a bit of a hack, ideally `MacroStmts` would not exist at all after HIR lowering, but that requires changing how the lowering code works.
-rw-r--r--crates/hir-def/src/body/lower.rs10
-rw-r--r--crates/hir-ty/src/tests/regression.rs17
2 files changed, 26 insertions, 1 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 66f9c24e872..f6ec8bf7e9e 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -551,9 +551,17 @@ impl ExprCollector<'_> {
                 }
             }
             ast::Expr::MacroStmts(e) => {
-                let statements = e.statements().filter_map(|s| self.collect_stmt(s)).collect();
+                let statements: Box<[_]> =
+                    e.statements().filter_map(|s| self.collect_stmt(s)).collect();
                 let tail = e.expr().map(|e| self.collect_expr(e));
 
+                if e.syntax().children().next().is_none() {
+                    // HACK: make sure that macros that expand to nothing aren't treated as a `()`
+                    // expression when used in block tail position.
+                    cov_mark::hit!(empty_macro_in_trailing_position_is_removed);
+                    return None;
+                }
+
                 self.alloc_expr(Expr::MacroStmts { tail, statements }, syntax_ptr)
             }
             ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 93a88ab58ef..1b5ed0603bf 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -1648,3 +1648,20 @@ fn main() {
         "#]],
     );
 }
+
+#[test]
+fn trailing_empty_macro() {
+    cov_mark::check!(empty_macro_in_trailing_position_is_removed);
+    check_no_mismatches(
+        r#"
+macro_rules! m2 {
+    ($($t:tt)*) => {$($t)*};
+}
+
+fn macrostmts() -> u8 {
+    m2! { 0 }
+    m2! {}
+}
+    "#,
+    );
+}