Skip to content

Commit ca62493

Browse files
Merge #10162
10162: feat: enable completions inside macros after `.` r=jonas-schievink a=jonas-schievink Fixes #8158 Fixes #10039 This issue was not caused by us not being able to expand the macro (we can do that just fine). Instead, body lowering deliberately aborted lowering of a statement macro expansion when the expansion causes errors, citing some hygiene-related issue with recovery (`@edwin0cheng` if you remember what exactly the issue was I'd be happy to take a look). Simply removing that code path doesn't cause any tests to fail, and makes completions in macros work better ("completion after `.`" is not the only thing that now works better, we also get better highlighting in incomplete macro calls). Just to be sure, lets merge this after tomorrow's release. Co-authored-by: Jonas Schievink <[email protected]>
2 parents b73b321 + 8e736da commit ca62493

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
lines changed

crates/hir_def/src/body/lower.rs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ impl ExprCollector<'_> {
558558
ast::Expr::MacroCall(e) => {
559559
let macro_ptr = AstPtr::new(&e);
560560
let mut ids = vec![];
561-
self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
561+
self.collect_macro_call(e, macro_ptr, |this, expansion| {
562562
ids.push(match expansion {
563563
Some(it) => this.collect_expr(it),
564564
None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()),
@@ -582,7 +582,6 @@ impl ExprCollector<'_> {
582582
&mut self,
583583
e: ast::MacroCall,
584584
syntax_ptr: AstPtr<ast::MacroCall>,
585-
is_error_recoverable: bool,
586585
mut collector: F,
587586
) {
588587
// File containing the macro call. Expansion errors will be attached here.
@@ -620,18 +619,11 @@ impl ExprCollector<'_> {
620619

621620
match res.value {
622621
Some((mark, expansion)) => {
623-
// FIXME: Statements are too complicated to recover from error for now.
624-
// It is because we don't have any hygiene for local variable expansion right now.
625-
if !is_error_recoverable && res.err.is_some() {
626-
self.expander.exit(self.db, mark);
627-
collector(self, None);
628-
} else {
629-
self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
622+
self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
630623

631-
let id = collector(self, Some(expansion));
632-
self.expander.exit(self.db, mark);
633-
id
634-
}
624+
let id = collector(self, Some(expansion));
625+
self.expander.exit(self.db, mark);
626+
id
635627
}
636628
None => collector(self, None),
637629
}
@@ -667,27 +659,21 @@ impl ExprCollector<'_> {
667659
let macro_ptr = AstPtr::new(&m);
668660
let syntax_ptr = AstPtr::new(&stmt.expr().unwrap());
669661

670-
self.collect_macro_call(
671-
m,
672-
macro_ptr,
673-
false,
674-
|this, expansion| match expansion {
675-
Some(expansion) => {
676-
let statements: ast::MacroStmts = expansion;
677-
678-
statements.statements().for_each(|stmt| this.collect_stmt(stmt));
679-
if let Some(expr) = statements.expr() {
680-
let expr = this.collect_expr(expr);
681-
this.statements_in_scope
682-
.push(Statement::Expr { expr, has_semi });
683-
}
684-
}
685-
None => {
686-
let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
662+
self.collect_macro_call(m, macro_ptr, |this, expansion| match expansion {
663+
Some(expansion) => {
664+
let statements: ast::MacroStmts = expansion;
665+
666+
statements.statements().for_each(|stmt| this.collect_stmt(stmt));
667+
if let Some(expr) = statements.expr() {
668+
let expr = this.collect_expr(expr);
687669
this.statements_in_scope.push(Statement::Expr { expr, has_semi });
688670
}
689-
},
690-
);
671+
}
672+
None => {
673+
let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone());
674+
this.statements_in_scope.push(Statement::Expr { expr, has_semi });
675+
}
676+
});
691677
} else {
692678
let expr = self.collect_expr_opt(stmt.expr());
693679
self.statements_in_scope.push(Statement::Expr { expr, has_semi });
@@ -889,7 +875,7 @@ impl ExprCollector<'_> {
889875
Some(call) => {
890876
let macro_ptr = AstPtr::new(&call);
891877
let mut pat = None;
892-
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
878+
self.collect_macro_call(call, macro_ptr, |this, expanded_pat| {
893879
pat = Some(this.collect_pat_opt(expanded_pat));
894880
});
895881

crates/ide_completion/src/completions/dot.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,29 @@ impl Foo { fn foo(&mut self) { $0 } }"#,
672672
"#]],
673673
);
674674
}
675+
676+
#[test]
677+
fn macro_completion_after_dot() {
678+
check(
679+
r#"
680+
macro_rules! m {
681+
($e:expr) => { $e };
682+
}
683+
684+
struct Completable;
685+
686+
impl Completable {
687+
fn method(&self) {}
688+
}
689+
690+
fn f() {
691+
let c = Completable;
692+
m!(c.$0);
693+
}
694+
"#,
695+
expect![[r#"
696+
me method() fn(&self)
697+
"#]],
698+
);
699+
}
675700
}

0 commit comments

Comments
 (0)