From 5bb10ae244facd131840cc66ca4e961a62eaef7c Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 2 Jan 2026 19:00:55 +0800 Subject: [PATCH 1/2] Fix some TryEnum reference assists - Fix `convert_to_guarded_return` - Fix `replace_let_with_if_let` - Fix `replace_if_let_with_match` --- .../src/handlers/convert_to_guarded_return.rs | 26 +++++++++++++++++++ .../src/handlers/desugar_try_expr.rs | 2 +- .../src/handlers/replace_if_let_with_match.rs | 25 ++++++++++++++++++ .../src/handlers/replace_let_with_if_let.rs | 23 ++++++++++++++++ .../ide-completion/src/completions/postfix.rs | 2 +- .../crates/ide-db/src/ty_filter.rs | 10 ++++++- 6 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index ea5c1637b760..dc51bf4b5b8c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -934,6 +934,32 @@ fn foo() -> Option { None } +fn main() { + let Some(x) = foo() else { return }; +} +"#, + ); + } + + #[test] + fn convert_let_ref_stmt_inside_fn() { + check_assist( + convert_to_guarded_return, + r#" +//- minicore: option +fn foo() -> &'static Option { + &None +} + +fn main() { + let x$0 = foo(); +} +"#, + r#" +fn foo() -> &'static Option { + &None +} + fn main() { let Some(x) = foo() else { return }; } diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs index 9976e34e730c..176eb1c4944e 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs @@ -61,7 +61,7 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let expr = try_expr.expr()?; let expr_type_info = ctx.sema.type_of_expr(&expr)?; - let try_enum = TryEnum::from_ty(&ctx.sema, &expr_type_info.original)?; + let try_enum = TryEnum::from_ty_without_strip(&ctx.sema, &expr_type_info.original)?; let target = try_expr.syntax().text_range(); acc.add( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index 915dd3ffcaf0..d2452f28c4d7 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -849,6 +849,31 @@ fn foo(x: Option) { ); } + #[test] + fn special_case_option_ref() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: option +fn foo(x: &Option) { + $0if let Some(x) = x { + println!("{}", x) + } else { + println!("none") + } +} +"#, + r#" +fn foo(x: &Option) { + match x { + Some(x) => println!("{}", x), + None => println!("none"), + } +} +"#, + ); + } + #[test] fn special_case_inverted_option() { check_assist( diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index 15977c420e64..5587f1b59c54 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs @@ -101,6 +101,29 @@ mod tests { use super::*; + #[test] + fn replace_let_try_enum_ref() { + check_assist( + replace_let_with_if_let, + r" +//- minicore: option +fn main(action: Action) { + $0let x = compute(); +} + +fn compute() -> &'static Option { &None } + ", + r" +fn main(action: Action) { + if let Some(x) = compute() { + } +} + +fn compute() -> &'static Option { &None } + ", + ) + } + #[test] fn replace_let_unknown_enum() { check_assist( diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs index 8e39b0aa5255..a58592b1365b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/postfix.rs @@ -110,7 +110,7 @@ pub(crate) fn complete_postfix( postfix_snippet("call", "function(expr)", &format!("${{1}}({receiver_text})")) .add_to(acc, ctx.db); - let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty.strip_references()); + let try_enum = TryEnum::from_ty(&ctx.sema, receiver_ty); let mut is_in_cond = false; if let Some(parent) = dot_receiver_including_refs.syntax().parent() && let Some(second_ancestor) = parent.parent() diff --git a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs index 095256d8294e..b5c43b3b369b 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/ty_filter.rs @@ -19,8 +19,16 @@ pub enum TryEnum { impl TryEnum { const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result]; - /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`. + /// Returns `Some(..)` if the provided `ty.strip_references()` is an enum that implements `std::ops::Try`. pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type<'_>) -> Option { + Self::from_ty_without_strip(sema, &ty.strip_references()) + } + + /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`. + pub fn from_ty_without_strip( + sema: &Semantics<'_, RootDatabase>, + ty: &hir::Type<'_>, + ) -> Option { let enum_ = match ty.as_adt() { Some(hir::Adt::Enum(it)) => it, _ => return None, From b5eb4f6767b26627c363bf9f6d43197f6bca47df Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 20 Feb 2026 18:19:01 +0800 Subject: [PATCH 2/2] Do strip references for desugar_try_expr --- .../crates/ide-assists/src/handlers/desugar_try_expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs index 176eb1c4944e..9976e34e730c 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/desugar_try_expr.rs @@ -61,7 +61,7 @@ pub(crate) fn desugar_try_expr(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let expr = try_expr.expr()?; let expr_type_info = ctx.sema.type_of_expr(&expr)?; - let try_enum = TryEnum::from_ty_without_strip(&ctx.sema, &expr_type_info.original)?; + let try_enum = TryEnum::from_ty(&ctx.sema, &expr_type_info.original)?; let target = try_expr.syntax().text_range(); acc.add(