@@ -6,7 +6,7 @@ use hir::{db::HirDatabase, AsAssocItem, HirDisplay};
6
6
use ide_db:: { SnippetCap , SymbolKind } ;
7
7
use itertools:: Itertools ;
8
8
use stdx:: { format_to, to_lower_snake_case} ;
9
- use syntax:: { ast, format_smolstr, AstNode , Edition , SmolStr , SyntaxKind , ToSmolStr , T } ;
9
+ use syntax:: { ast, format_smolstr, match_ast , AstNode , Edition , SmolStr , SyntaxKind , ToSmolStr , T } ;
10
10
11
11
use crate :: {
12
12
context:: { CompletionContext , DotAccess , DotAccessKind , PathCompletionCtx , PathKind } ,
@@ -278,31 +278,44 @@ pub(super) fn add_call_parens<'b>(
278
278
( snippet, "(…)" )
279
279
} ;
280
280
if ret_type. is_unit ( ) && ctx. config . add_semicolon_to_unit {
281
- let next_non_trivia_token =
282
- std:: iter:: successors ( ctx. token . next_token ( ) , |it| it. next_token ( ) )
283
- . find ( |it| !it. kind ( ) . is_trivia ( ) ) ;
284
- let in_match_arm = ctx. token . parent_ancestors ( ) . try_for_each ( |ancestor| {
285
- if ast:: MatchArm :: can_cast ( ancestor. kind ( ) ) {
286
- ControlFlow :: Break ( true )
287
- } else if matches ! ( ancestor. kind( ) , SyntaxKind :: EXPR_STMT | SyntaxKind :: BLOCK_EXPR ) {
288
- ControlFlow :: Break ( false )
289
- } else {
290
- ControlFlow :: Continue ( ( ) )
281
+ let inside_closure_ret = ctx. token . parent_ancestors ( ) . try_for_each ( |ancestor| {
282
+ match_ast ! {
283
+ match ancestor {
284
+ ast:: BlockExpr ( _) => ControlFlow :: Break ( false ) ,
285
+ ast:: ClosureExpr ( _) => ControlFlow :: Break ( true ) ,
286
+ _ => ControlFlow :: Continue ( ( ) )
287
+ }
291
288
}
292
289
} ) ;
293
- // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node.
294
- let in_match_arm = match in_match_arm {
295
- ControlFlow :: Continue ( ( ) ) => false ,
296
- ControlFlow :: Break ( it) => it,
297
- } ;
298
- let complete_token = if in_match_arm { T ! [ , ] } else { T ! [ ; ] } ;
299
- if next_non_trivia_token. map ( |it| it. kind ( ) ) != Some ( complete_token) {
300
- cov_mark:: hit!( complete_semicolon) ;
301
- let ch = if in_match_arm { ',' } else { ';' } ;
302
- if snippet. ends_with ( "$0" ) {
303
- snippet. insert ( snippet. len ( ) - "$0" . len ( ) , ch) ;
304
- } else {
305
- snippet. push ( ch) ;
290
+
291
+ if inside_closure_ret != ControlFlow :: Break ( true ) {
292
+ let next_non_trivia_token =
293
+ std:: iter:: successors ( ctx. token . next_token ( ) , |it| it. next_token ( ) )
294
+ . find ( |it| !it. kind ( ) . is_trivia ( ) ) ;
295
+ let in_match_arm = ctx. token . parent_ancestors ( ) . try_for_each ( |ancestor| {
296
+ if ast:: MatchArm :: can_cast ( ancestor. kind ( ) ) {
297
+ ControlFlow :: Break ( true )
298
+ } else if matches ! ( ancestor. kind( ) , SyntaxKind :: EXPR_STMT | SyntaxKind :: BLOCK_EXPR )
299
+ {
300
+ ControlFlow :: Break ( false )
301
+ } else {
302
+ ControlFlow :: Continue ( ( ) )
303
+ }
304
+ } ) ;
305
+ // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node.
306
+ let in_match_arm = match in_match_arm {
307
+ ControlFlow :: Continue ( ( ) ) => false ,
308
+ ControlFlow :: Break ( it) => it,
309
+ } ;
310
+ let complete_token = if in_match_arm { T ! [ , ] } else { T ! [ ; ] } ;
311
+ if next_non_trivia_token. map ( |it| it. kind ( ) ) != Some ( complete_token) {
312
+ cov_mark:: hit!( complete_semicolon) ;
313
+ let ch = if in_match_arm { ',' } else { ';' } ;
314
+ if snippet. ends_with ( "$0" ) {
315
+ snippet. insert ( snippet. len ( ) - "$0" . len ( ) , ch) ;
316
+ } else {
317
+ snippet. push ( ch) ;
318
+ }
306
319
}
307
320
}
308
321
}
@@ -886,6 +899,27 @@ fn bar() {
886
899
v => foo()$0,
887
900
}
888
901
}
902
+ "# ,
903
+ ) ;
904
+ }
905
+
906
+ #[ test]
907
+ fn no_semicolon_in_closure_ret ( ) {
908
+ check_edit (
909
+ r#"foo"# ,
910
+ r#"
911
+ fn foo() {}
912
+ fn baz(_: impl FnOnce()) {}
913
+ fn bar() {
914
+ baz(|| fo$0);
915
+ }
916
+ "# ,
917
+ r#"
918
+ fn foo() {}
919
+ fn baz(_: impl FnOnce()) {}
920
+ fn bar() {
921
+ baz(|| foo()$0);
922
+ }
889
923
"# ,
890
924
) ;
891
925
}
0 commit comments