Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-assists/src/handlers/convert_to_guarded_return.rs26
-rw-r--r--crates/ide-assists/src/handlers/desugar_try_expr.rs2
-rw-r--r--crates/ide-assists/src/handlers/replace_if_let_with_match.rs25
-rw-r--r--crates/ide-assists/src/handlers/replace_let_with_if_let.rs23
-rw-r--r--crates/ide-completion/src/completions/postfix.rs2
-rw-r--r--crates/ide-db/src/ty_filter.rs10
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,