@@ -24,24 +24,30 @@ pub(crate) fn non_exhaustive_let(
2424 . stable ( )
2525 . with_fixes ( fixes ( & ctx. sema , d) )
2626}
27+
2728fn 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