about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-05 22:34:59 +0000
committerGitHub <noreply@github.com>2022-03-05 22:34:59 +0000
commitb032993733d82ecca50e61f93454b49bca4ba236 (patch)
treeb9bb0adeceb41066f2e28af7a5c064793894b5fe
parent8f504dc87384b0fa41a55327566f0db9c08eb98c (diff)
parenta148c49f1c5b1e30dfc112edbf79ca4cbabc5946 (diff)
downloadrust-b032993733d82ecca50e61f93454b49bca4ba236.tar.gz
rust-b032993733d82ecca50e61f93454b49bca4ba236.zip
Merge #11629
11629: fix: Fix macro-calls expanding to items in if/while conditions r=Veykril a=Veykril

Fixes https://github.com/rust-analyzer/rust-analyzer/issues/11617

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-rw-r--r--crates/hir_def/src/body/lower.rs16
-rw-r--r--crates/hir_expand/src/lib.rs32
-rw-r--r--crates/hir_ty/src/tests/macros.rs4
3 files changed, 30 insertions, 22 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index f86f4f3c85b..ca337bd0057 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -507,14 +507,14 @@ impl ExprCollector<'_> {
             }
             ast::Expr::MacroCall(e) => {
                 let macro_ptr = AstPtr::new(&e);
-                let mut ids = vec![];
+                let mut ids = None;
                 self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
-                    ids.push(match expansion {
+                    ids.get_or_insert(match expansion {
                         Some(it) => this.collect_expr(it),
                         None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
-                    })
+                    });
                 });
-                ids[0]
+                ids.unwrap_or_else(|| self.alloc_expr(Expr::Missing, syntax_ptr.clone()))
             }
             ast::Expr::MacroStmts(e) => {
                 e.statements().for_each(|s| self.collect_stmt(s));
@@ -531,7 +531,7 @@ impl ExprCollector<'_> {
 
     fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>(
         &mut self,
-        e: ast::MacroCall,
+        mcall: ast::MacroCall,
         syntax_ptr: AstPtr<ast::MacroCall>,
         record_diagnostics: bool,
         mut collector: F,
@@ -539,8 +539,8 @@ impl ExprCollector<'_> {
         // File containing the macro call. Expansion errors will be attached here.
         let outer_file = self.expander.current_file_id;
 
-        let macro_call = self.expander.to_source(AstPtr::new(&e));
-        let res = self.expander.enter_expand(self.db, e);
+        let macro_call_ptr = self.expander.to_source(AstPtr::new(&mcall));
+        let res = self.expander.enter_expand(self.db, mcall);
 
         let res = match res {
             Ok(res) => res,
@@ -575,7 +575,7 @@ impl ExprCollector<'_> {
 
         match res.value {
             Some((mark, expansion)) => {
-                self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
+                self.source_map.expansions.insert(macro_call_ptr, self.expander.current_file_id);
 
                 let id = collector(self, Some(expansion));
                 self.expander.exit(self.db, mark);
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index ba0f1015124..bdb01ca1701 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -890,19 +890,27 @@ impl ExpandTo {
             MACRO_PAT => ExpandTo::Pattern,
             MACRO_TYPE => ExpandTo::Type,
 
-            ARG_LIST | TRY_EXPR | TUPLE_EXPR | PAREN_EXPR | ARRAY_EXPR | FOR_EXPR | PATH_EXPR
-            | CLOSURE_EXPR | BREAK_EXPR | RETURN_EXPR | MATCH_EXPR | MATCH_ARM | MATCH_GUARD
-            | RECORD_EXPR_FIELD | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR
-            | AWAIT_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR
-            | LET_EXPR => ExpandTo::Expr,
-            LET_STMT => {
-                // FIXME: Handle LHS Pattern
-                ExpandTo::Expr
-            }
-
+            ARG_LIST | ARRAY_EXPR | AWAIT_EXPR | BIN_EXPR | BREAK_EXPR | CALL_EXPR | CAST_EXPR
+            | CLOSURE_EXPR | FIELD_EXPR | FOR_EXPR | IF_EXPR | INDEX_EXPR | LET_EXPR
+            | MATCH_ARM | MATCH_EXPR | MATCH_GUARD | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR
+            | PREFIX_EXPR | RANGE_EXPR | RECORD_EXPR_FIELD | REF_EXPR | RETURN_EXPR | TRY_EXPR
+            | TUPLE_EXPR | WHILE_EXPR => ExpandTo::Expr,
             _ => {
-                // Unknown , Just guess it is `Items`
-                ExpandTo::Items
+                match ast::LetStmt::cast(parent) {
+                    Some(let_stmt) => {
+                        if let Some(true) = let_stmt.initializer().map(|it| it.syntax() == syn) {
+                            ExpandTo::Expr
+                        } else if let Some(true) = let_stmt.ty().map(|it| it.syntax() == syn) {
+                            ExpandTo::Type
+                        } else {
+                            ExpandTo::Pattern
+                        }
+                    }
+                    None => {
+                        // Unknown , Just guess it is `Items`
+                        ExpandTo::Items
+                    }
+                }
             }
         }
     }
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index 344e7293c59..a61175f2733 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -190,6 +190,7 @@ fn expr_macro_def_expanded_in_various_places() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
+            !0..6 '1isize': isize
             39..442 '{     ...!(); }': ()
             73..94 'spam!(...am!())': {unknown}
             100..119 'for _ ...!() {}': ()
@@ -197,7 +198,6 @@ fn expr_macro_def_expanded_in_various_places() {
             117..119 '{}': ()
             124..134 '|| spam!()': || -> isize
             140..156 'while ...!() {}': ()
-            146..153 'spam!()': bool
             154..156 '{}': ()
             161..174 'break spam!()': !
             180..194 'return spam!()': !
@@ -271,6 +271,7 @@ fn expr_macro_rules_expanded_in_various_places() {
             !0..6 '1isize': isize
             !0..6 '1isize': isize
             !0..6 '1isize': isize
+            !0..6 '1isize': isize
             53..456 '{     ...!(); }': ()
             87..108 'spam!(...am!())': {unknown}
             114..133 'for _ ...!() {}': ()
@@ -278,7 +279,6 @@ fn expr_macro_rules_expanded_in_various_places() {
             131..133 '{}': ()
             138..148 '|| spam!()': || -> isize
             154..170 'while ...!() {}': ()
-            160..167 'spam!()': bool
             168..170 '{}': ()
             175..188 'break spam!()': !
             194..208 'return spam!()': !