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 08b114072fd9..db8c82b3f3b7 100644 --- a/crates/ide-assists/src/handlers/convert_to_guarded_return.rs +++ b/crates/ide-assists/src/handlers/convert_to_guarded_return.rs @@ -193,8 +193,10 @@ fn let_stmt_to_guarded_return( return None; } - let try_enum = - ctx.sema.type_of_expr(&expr).and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))?; + let try_enum = ctx + .sema + .type_of_expr(&expr) + .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted().strip_references()))?; let happy_pattern = try_enum.happy_pattern(pat); let target = let_stmt.syntax().text_range(); @@ -241,13 +243,14 @@ fn early_expression( }; if let Some(fn_) = ast::Fn::cast(parent_container.clone()) && let Some(fn_def) = sema.to_def(&fn_) - && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &fn_def.ret_type(sema.db)) + && let Some(TryEnum::Option) = + TryEnum::from_ty(sema, &fn_def.ret_type(sema.db).strip_references()) { return Some(return_none_expr()); } if let Some(body) = ast::ClosureExpr::cast(parent_container.clone()).and_then(|it| it.body()) && let Some(ret_ty) = sema.type_of_expr(&body).map(TypeInfo::original) - && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &ret_ty) + && let Some(TryEnum::Option) = TryEnum::from_ty(sema, &ret_ty.strip_references()) { return Some(return_none_expr()); } @@ -902,6 +905,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/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index b7e5344712eb..a13f52709b60 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 @@ -160,7 +160,7 @@ fn make_else_arm( [(Some(pat), _, _)] => match ctx .sema .type_of_pat(pat) - .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted())) + .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted().strip_references())) { Some(it) => { if does_pat_match_variant(pat, &it.sad_pattern()) { @@ -384,7 +384,7 @@ fn binds_name(sema: &hir::Semantics<'_, RootDatabase>, pat: &ast::Pat) -> bool { fn is_sad_pat(sema: &hir::Semantics<'_, RootDatabase>, pat: &ast::Pat) -> bool { sema.type_of_pat(pat) - .and_then(|ty| TryEnum::from_ty(sema, &ty.adjusted())) + .and_then(|ty| TryEnum::from_ty(sema, &ty.adjusted().strip_references())) .is_some_and(|it| does_pat_match_variant(pat, &it.sad_pattern())) } @@ -847,6 +847,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/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/crates/ide-assists/src/handlers/replace_let_with_if_let.rs index b95e9b52b053..6b9d79d7ae54 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 @@ -51,7 +51,7 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_> original_pat } else { let happy_variant = ty - .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted())) + .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted().strip_references())) .map(|it| it.happy_case()); match happy_variant { None => original_pat, @@ -97,6 +97,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(