Unnamed repository; edit this file 'description' to name the repository.
Fix some TryEnum reference assists
- Fix `convert_to_guarded_return`
- Fix `replace_let_with_if_let`
- Fix `replace_if_let_with_match`
6 files changed, 85 insertions, 3 deletions
diff --git a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs index ea5c1637b7..dc51bf4b5b 100644 --- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -942,6 +942,32 @@ fn main() { } #[test] + fn convert_let_ref_stmt_inside_fn() { + check_assist( + convert_to_guarded_return, + r#" +//- minicore: option +fn foo() -> &'static Option<i32> { + &None +} + +fn main() { + let x$0 = foo(); +} +"#, + r#" +fn foo() -> &'static Option<i32> { + &None +} + +fn main() { + let Some(x) = foo() else { return }; +} +"#, + ); + } + + #[test] fn convert_let_stmt_inside_fn_return_option() { check_assist( convert_to_guarded_return, diff --git a/crates/ide-assists/src/handlers/desugar_try_expr.rs b/crates/ide-assists/src/handlers/desugar_try_expr.rs index 9976e34e73..176eb1c494 100644 --- a/crates/ide-assists/src/handlers/desugar_try_expr.rs +++ b/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/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index 915dd3ffca..d2452f28c4 100644 --- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -850,6 +850,31 @@ fn foo(x: Option<i32>) { } #[test] + fn special_case_option_ref() { + check_assist( + replace_if_let_with_match, + r#" +//- minicore: option +fn foo(x: &Option<i32>) { + $0if let Some(x) = x { + println!("{}", x) + } else { + println!("none") + } +} +"#, + r#" +fn foo(x: &Option<i32>) { + match x { + Some(x) => println!("{}", x), + None => println!("none"), + } +} +"#, + ); + } + + #[test] fn special_case_inverted_option() { check_assist( replace_if_let_with_match, diff --git a/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index 15977c420e..5587f1b59c 100644 --- a/crates/ide-assists/src/handlers/replace_let_with_if_let.rs +++ b/crates/ide-assists/src/handlers/replace_let_with_if_let.rs @@ -102,6 +102,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<i32> { &None } + ", + r" +fn main(action: Action) { + if let Some(x) = compute() { + } +} + +fn compute() -> &'static Option<i32> { &None } + ", + ) + } + + #[test] fn replace_let_unknown_enum() { check_assist( replace_let_with_if_let, diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 8e39b0aa52..a58592b136 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/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/crates/ide-db/src/ty_filter.rs b/crates/ide-db/src/ty_filter.rs index 095256d829..b5c43b3b36 100644 --- a/crates/ide-db/src/ty_filter.rs +++ b/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<TryEnum> { + 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<TryEnum> { let enum_ = match ty.as_adt() { Some(hir::Adt::Enum(it)) => it, _ => return None, |