@@ -30,7 +30,7 @@ use crate::{
3030// ```
3131pub ( crate ) fn convert_match_to_let_else ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
3232 let let_stmt: ast:: LetStmt = ctx. find_node_at_offset ( ) ?;
33- let binding = find_binding ( let_stmt. pat ( ) ? ) ?;
33+ let binding = let_stmt. pat ( ) ?;
3434
3535 let initializer = match let_stmt. initializer ( ) {
3636 Some ( ast:: Expr :: MatchExpr ( it) ) => it,
@@ -47,7 +47,12 @@ pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'
4747 return None ;
4848 }
4949
50- let diverging_arm_expr = diverging_arm. expr ( ) ?;
50+ let diverging_arm_expr = match diverging_arm. expr ( ) ? {
51+ ast:: Expr :: BlockExpr ( block) if block. modifier ( ) . is_none ( ) && block. label ( ) . is_none ( ) => {
52+ block. to_string ( )
53+ }
54+ other => format ! ( "{{ {other} }}" ) ,
55+ } ;
5156 let extracting_arm_pat = extracting_arm. pat ( ) ?;
5257 let extracted_variable = find_extracted_variable ( ctx, & extracting_arm) ?;
5358
@@ -56,24 +61,16 @@ pub(crate) fn convert_match_to_let_else(acc: &mut Assists, ctx: &AssistContext<'
5661 "Convert match to let-else" ,
5762 let_stmt. syntax ( ) . text_range ( ) ,
5863 |builder| {
59- let extracting_arm_pat = rename_variable ( & extracting_arm_pat, extracted_variable, binding) ;
64+ let extracting_arm_pat =
65+ rename_variable ( & extracting_arm_pat, extracted_variable, binding) ;
6066 builder. replace (
6167 let_stmt. syntax ( ) . text_range ( ) ,
62- format ! ( "let {extracting_arm_pat} = {initializer_expr} else {{ { diverging_arm_expr} }} ;" )
68+ format ! ( "let {extracting_arm_pat} = {initializer_expr} else {diverging_arm_expr};" ) ,
6369 )
6470 } ,
6571 )
6672}
6773
68- // Given a pattern, find the name introduced to the surrounding scope.
69- fn find_binding ( pat : ast:: Pat ) -> Option < ast:: IdentPat > {
70- if let ast:: Pat :: IdentPat ( ident) = pat {
71- Some ( ident)
72- } else {
73- None
74- }
75- }
76-
7774// Given a match expression, find extracting and diverging arms.
7875fn find_arms (
7976 ctx : & AssistContext < ' _ > ,
@@ -124,7 +121,7 @@ fn find_extracted_variable(ctx: &AssistContext<'_>, arm: &ast::MatchArm) -> Opti
124121}
125122
126123// Rename `extracted` with `binding` in `pat`.
127- fn rename_variable ( pat : & ast:: Pat , extracted : ast:: Name , binding : ast:: IdentPat ) -> SyntaxNode {
124+ fn rename_variable ( pat : & ast:: Pat , extracted : ast:: Name , binding : ast:: Pat ) -> SyntaxNode {
128125 let syntax = pat. syntax ( ) . clone_for_update ( ) ;
129126 let extracted_syntax = syntax. covering_element ( extracted. syntax ( ) . text_range ( ) ) ;
130127
@@ -136,7 +133,7 @@ fn rename_variable(pat: &ast::Pat, extracted: ast::Name, binding: ast::IdentPat)
136133 if let Some ( name_ref) = record_pat_field. field_name ( ) {
137134 ted:: replace (
138135 record_pat_field. syntax ( ) ,
139- ast:: make:: record_pat_field ( ast:: make:: name_ref ( & name_ref. text ( ) ) , binding. into ( ) )
136+ ast:: make:: record_pat_field ( ast:: make:: name_ref ( & name_ref. text ( ) ) , binding)
140137 . syntax ( )
141138 . clone_for_update ( ) ,
142139 ) ;
@@ -410,4 +407,52 @@ fn foo(opt: Option<i32>) -> Option<i32> {
410407 "# ,
411408 ) ;
412409 }
410+
411+ #[ test]
412+ fn complex_pattern ( ) {
413+ check_assist (
414+ convert_match_to_let_else,
415+ r#"
416+ //- minicore: option
417+ fn f() {
418+ let (x, y) = $0match Some((0, 1)) {
419+ Some(it) => it,
420+ None => return,
421+ };
422+ }
423+ "# ,
424+ r#"
425+ fn f() {
426+ let Some((x, y)) = Some((0, 1)) else { return };
427+ }
428+ "# ,
429+ ) ;
430+ }
431+
432+ #[ test]
433+ fn diverging_block ( ) {
434+ check_assist (
435+ convert_match_to_let_else,
436+ r#"
437+ //- minicore: option
438+ fn f() {
439+ let x = $0match Some(()) {
440+ Some(it) => it,
441+ None => {//comment
442+ println!("nope");
443+ return
444+ },
445+ };
446+ }
447+ "# ,
448+ r#"
449+ fn f() {
450+ let Some(x) = Some(()) else {//comment
451+ println!("nope");
452+ return
453+ };
454+ }
455+ "# ,
456+ ) ;
457+ }
413458}
0 commit comments