diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index a846ffe10e..e071547141 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -75,6 +75,11 @@ pub(crate) fn complete_postfix( let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references()); if let Some(try_enum) = &try_enum { + let in_loop = dot_receiver + .syntax() + .ancestors() + .any(|n| matches!(n.kind(), WHILE_EXPR | LOOP_EXPR | FOR_EXPR)); + match try_enum { TryEnum::Result => { postfix_snippet( @@ -84,6 +89,17 @@ pub(crate) fn complete_postfix( ) .add_to(acc, ctx.db); + postfix_snippet( + "lete", + "let Ok else {}", + &if in_loop { + format!("let Ok($1) = {receiver_text} else {{\n ${{2|continue,break,return|}};\n}};\n$0") + } else { + format!("let Ok($1) = {receiver_text} else {{\n return;\n}};\n$0") + }, + ) + .add_to(acc, ctx.db); + postfix_snippet( "while", "while let Ok {}", @@ -99,6 +115,17 @@ pub(crate) fn complete_postfix( ) .add_to(acc, ctx.db); + postfix_snippet( + "lete", + "let Some else {}", + &if in_loop { + format!("let Some($1) = {receiver_text} else {{\n ${{2|continue,break,return|}};\n}};\n$0") + } else { + format!("let Some($1) = {receiver_text} else {{\n return;\n}};\n$0") + }, + ) + .add_to(acc, ctx.db); + postfix_snippet( "while", "while let Some {}", @@ -469,6 +496,56 @@ fn main() { ); } + #[test] + fn option_letelse() { + check_edit( + "lete", + r#" +//- minicore: option +fn main() { + let bar = Some(true); + bar.$0 +} +"#, + r#" +fn main() { + let bar = Some(true); + let Some($1) = bar else { + return; +}; +$0 +} +"#, + ); + } + + #[test] + fn option_letelse_loop() { + check_edit( + "lete", + r#" +//- minicore: option +fn main() { + let bar = Some(true); + loop { + bar.$0 + } +} +"#, + r#" +fn main() { + let bar = Some(true); + loop { + let Some($1) = bar else { + ${2|continue,break,return|}; +}; +$0 + } +} +"#, + ); + } + #[test] fn result_match() { check_edit(