Turn unresolved proc macro expansions into missing expressions

This commit is contained in:
Lukas Wirth 2023-08-05 20:00:33 +02:00
parent c59bd2dc3f
commit 042be329a7
4 changed files with 24 additions and 19 deletions

View File

@ -913,15 +913,14 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr) self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr)
} }
fn collect_macro_call<F, T, U>( fn collect_macro_call<T, U>(
&mut self, &mut self,
mcall: ast::MacroCall, mcall: ast::MacroCall,
syntax_ptr: AstPtr<ast::MacroCall>, syntax_ptr: AstPtr<ast::MacroCall>,
record_diagnostics: bool, record_diagnostics: bool,
collector: F, collector: impl FnOnce(&mut Self, Option<T>) -> U,
) -> U ) -> U
where where
F: FnOnce(&mut Self, Option<T>) -> U,
T: ast::AstNode, T: ast::AstNode,
{ {
// File containing the macro call. Expansion errors will be attached here. // File containing the macro call. Expansion errors will be attached here.

View File

@ -164,18 +164,26 @@ impl Expander {
return ExpandResult { value: None, err }; return ExpandResult { value: None, err };
}; };
Self::enter_expand_inner(db, call_id, err).map(|value| { let res = Self::enter_expand_inner(db, call_id, err);
value.and_then(|InFile { file_id, value }| { match res.err {
let parse = value.cast::<T>()?; // If proc-macro is disabled or unresolved, we want to expand to a missing expression
// instead of an empty tree which might end up in an empty block.
Some(ExpandError::UnresolvedProcMacro(_)) => res.map(|_| None),
_ => res.map(|value| {
value.and_then(|InFile { file_id, value }| {
let parse = value.cast::<T>()?;
self.recursion_depth += 1; self.recursion_depth += 1;
self.hygiene = Hygiene::new(db.upcast(), file_id); self.hygiene = Hygiene::new(db.upcast(), file_id);
let old_file_id = std::mem::replace(&mut self.current_file_id, file_id); let old_file_id = std::mem::replace(&mut self.current_file_id, file_id);
let mark = let mark = Mark {
Mark { file_id: old_file_id, bomb: DropBomb::new("expansion mark dropped") }; file_id: old_file_id,
Some((mark, parse)) bomb: DropBomb::new("expansion mark dropped"),
}) };
}) Some((mark, parse))
})
}),
}
} }
} }

View File

@ -37,11 +37,10 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
let unexpanded = ctx.find_node_at_offset::<ast::MacroCall>()?; let unexpanded = ctx.find_node_at_offset::<ast::MacroCall>()?;
let expanded = insert_ws_into(ctx.sema.expand(&unexpanded)?.clone_for_update()); let expanded = insert_ws_into(ctx.sema.expand(&unexpanded)?.clone_for_update());
let text_range = unexpanded.syntax().text_range(); let text_range = unexpanded.syntax().text_range();
acc.add( acc.add(
AssistId("inline_macro", AssistKind::RefactorRewrite), AssistId("inline_macro", AssistKind::RefactorInline),
format!("Inline macro"), format!("Inline macro"),
text_range, text_range,
|builder| builder.replace(text_range, expanded.to_string()), |builder| builder.replace(text_range, expanded.to_string()),

View File

@ -328,9 +328,6 @@ fn macro_rules(p: &mut Parser<'_>, m: Marker) {
p.bump_remap(T![macro_rules]); p.bump_remap(T![macro_rules]);
p.expect(T![!]); p.expect(T![!]);
if p.at(IDENT) {
name(p);
}
// Special-case `macro_rules! try`. // Special-case `macro_rules! try`.
// This is a hack until we do proper edition support // This is a hack until we do proper edition support
@ -340,6 +337,8 @@ fn macro_rules(p: &mut Parser<'_>, m: Marker) {
let m = p.start(); let m = p.start();
p.bump_remap(IDENT); p.bump_remap(IDENT);
m.complete(p, NAME); m.complete(p, NAME);
} else {
name(p);
} }
match p.current() { match p.current() {