@@ -11,12 +11,12 @@ use ide_db::{
1111 text_edit:: TextEdit ,
1212 ty_filter:: TryEnum ,
1313} ;
14- use itertools:: Either ;
1514use stdx:: never;
1615use syntax:: {
1716 SyntaxKind :: { BLOCK_EXPR , EXPR_STMT , FOR_EXPR , IF_EXPR , LOOP_EXPR , STMT_LIST , WHILE_EXPR } ,
18- TextRange , TextSize ,
17+ T , TextRange , TextSize ,
1918 ast:: { self , AstNode , AstToken } ,
19+ match_ast,
2020} ;
2121
2222use crate :: {
@@ -113,12 +113,8 @@ pub(crate) fn complete_postfix(
113113 if let Some ( parent) = dot_receiver_including_refs. syntax ( ) . parent ( )
114114 && let Some ( second_ancestor) = parent. parent ( )
115115 {
116- let sec_ancestor_kind = second_ancestor. kind ( ) ;
117- if let Some ( expr) = <Either < ast:: IfExpr , ast:: WhileExpr > >:: cast ( second_ancestor) {
118- is_in_cond = match expr {
119- Either :: Left ( it) => it. condition ( ) . is_some_and ( |cond| * cond. syntax ( ) == parent) ,
120- Either :: Right ( it) => it. condition ( ) . is_some_and ( |cond| * cond. syntax ( ) == parent) ,
121- }
116+ if let Some ( parent_expr) = ast:: Expr :: cast ( parent) {
117+ is_in_cond = is_in_condition ( & parent_expr) ;
122118 }
123119 match & try_enum {
124120 Some ( try_enum) if is_in_cond => match try_enum {
@@ -147,7 +143,7 @@ pub(crate) fn complete_postfix(
147143 . add_to ( acc, ctx. db ) ;
148144 }
149145 } ,
150- _ if matches ! ( sec_ancestor_kind , STMT_LIST | EXPR_STMT ) => {
146+ _ if matches ! ( second_ancestor . kind ( ) , STMT_LIST | EXPR_STMT ) => {
151147 postfix_snippet ( "let" , "let" , & format ! ( "let $0 = {receiver_text};" ) )
152148 . add_to ( acc, ctx. db ) ;
153149 postfix_snippet ( "letm" , "let mut" , & format ! ( "let mut $0 = {receiver_text};" ) )
@@ -454,6 +450,22 @@ fn add_custom_postfix_completions(
454450 None
455451}
456452
453+ pub ( crate ) fn is_in_condition ( it : & ast:: Expr ) -> bool {
454+ it. syntax ( )
455+ . parent ( )
456+ . and_then ( |parent| {
457+ Some ( match_ast ! { match parent {
458+ ast:: IfExpr ( expr) => expr. condition( ) ? == * it,
459+ ast:: WhileExpr ( expr) => expr. condition( ) ? == * it,
460+ ast:: MatchGuard ( guard) => guard. condition( ) ? == * it,
461+ ast:: BinExpr ( bin_expr) => ( bin_expr. op_token( ) ?. kind( ) == T ![ &&] )
462+ . then( || is_in_condition( & bin_expr. into( ) ) ) ?,
463+ _ => return None ,
464+ } } )
465+ } )
466+ . unwrap_or ( false )
467+ }
468+
457469#[ cfg( test) ]
458470mod tests {
459471 use expect_test:: expect;
@@ -648,6 +660,38 @@ fn main() {
648660 let bar = Some(true);
649661 if let Some($0) = bar
650662}
663+ "# ,
664+ ) ;
665+ check_edit (
666+ "let" ,
667+ r#"
668+ //- minicore: option
669+ fn main() {
670+ let bar = Some(true);
671+ if true && bar.$0
672+ }
673+ "# ,
674+ r#"
675+ fn main() {
676+ let bar = Some(true);
677+ if true && let Some($0) = bar
678+ }
679+ "# ,
680+ ) ;
681+ check_edit (
682+ "let" ,
683+ r#"
684+ //- minicore: option
685+ fn main() {
686+ let bar = Some(true);
687+ if true && true && bar.$0
688+ }
689+ "# ,
690+ r#"
691+ fn main() {
692+ let bar = Some(true);
693+ if true && true && let Some($0) = bar
694+ }
651695"# ,
652696 ) ;
653697 }
0 commit comments