Skip to content

Commit e837d66

Browse files
committed
Support unmap macro expansion
1 parent fa7a6d3 commit e837d66

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

crates/ide-diagnostics/src/handlers/non_exhaustive_let.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,30 @@ pub(crate) fn non_exhaustive_let(
2424
.stable()
2525
.with_fixes(fixes(&ctx.sema, d))
2626
}
27+
2728
fn fixes(sema: &Semantics<'_, RootDatabase>, d: &hir::NonExhaustiveLet) -> Option<Vec<Assist>> {
2829
let root = sema.parse_or_expand(d.pat.file_id);
2930
let pat = d.pat.value.to_node(&root);
3031
let let_stmt = ast::LetStmt::cast(pat.syntax().parent()?)?;
31-
let early_node = let_stmt.syntax().ancestors().find_map(AstNode::cast)?;
32+
let early_node =
33+
sema.ancestors_with_macros(let_stmt.syntax().clone()).find_map(AstNode::cast)?;
3234
let early_text = early_text(sema, &early_node);
3335

3436
if let_stmt.let_else().is_some() {
3537
return None;
3638
}
37-
38-
let file_id = d.pat.file_id.file_id()?.file_id(sema.db);
39+
let hir::FileRangeWrapper { file_id, range } = sema.original_range_opt(let_stmt.syntax())?;
40+
let insert_offset = if let Some(semicolon) = let_stmt.semicolon_token()
41+
&& let Some(token) = sema.parse(file_id).syntax().token_at_offset(range.end()).left_biased()
42+
&& token.kind() == semicolon.kind()
43+
{
44+
token.text_range().start()
45+
} else {
46+
range.end()
47+
};
3948
let semicolon = if let_stmt.semicolon_token().is_none() { ";" } else { "" };
4049
let else_block = format!(" else {{ {early_text} }}{semicolon}");
41-
let insert_offset = let_stmt
42-
.semicolon_token()
43-
.map(|it| it.text_range().start())
44-
.unwrap_or_else(|| let_stmt.syntax().text_range().end());
50+
let file_id = file_id.file_id(sema.db);
4551

4652
let source_change =
4753
SourceChange::from_text_edit(file_id, TextEdit::insert(insert_offset, else_block));
@@ -234,6 +240,29 @@ fn foo() {
234240
);
235241
}
236242

243+
#[test]
244+
fn fix_return_in_macro_expanded() {
245+
check_fix(
246+
r#"
247+
//- minicore: option
248+
macro_rules! identity { ($($t:tt)*) => { $($t)* }; }
249+
fn foo() {
250+
identity! {
251+
let None$0 = Some(5);
252+
}
253+
}
254+
"#,
255+
r#"
256+
macro_rules! identity { ($($t:tt)*) => { $($t)* }; }
257+
fn foo() {
258+
identity! {
259+
let None = Some(5) else { return };
260+
}
261+
}
262+
"#,
263+
);
264+
}
265+
237266
#[test]
238267
fn fix_return_in_incomplete_let() {
239268
check_fix(

0 commit comments

Comments
 (0)