about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates
diff options
context:
space:
mode:
authorA4-Tacks <wdsjxhno1001@163.com>2025-09-25 21:57:45 +0800
committerA4-Tacks <wdsjxhno1001@163.com>2025-09-25 22:04:53 +0800
commit11c35cd0bcb6e0c285be031f10d14d64bbf2bd9c (patch)
tree1b33ed5e9de3924a20f8ebc48d8b3ef3e9ceed44 /src/tools/rust-analyzer/crates
parent1947949f3d7212c181049d96e2665481d3bddc6b (diff)
downloadrust-11c35cd0bcb6e0c285be031f10d14d64bbf2bd9c.tar.gz
rust-11c35cd0bcb6e0c285be031f10d14d64bbf2bd9c.zip
Add applicable in closure for convert_to_guarded_return
Example
---
```rust
fn main() {
    let _f = || {
        bar();
        if$0 true {
            foo();

            // comment
            bar();
        }
    }
}
```
->
```rust
fn main() {
    let _f = || {
        bar();
        if false {
            return;
        }
        foo();

        // comment
        bar();
    }
}
```
Diffstat (limited to 'src/tools/rust-analyzer/crates')
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs54
1 files changed, 49 insertions, 5 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 aee9ce7878b..82213ae3217 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
@@ -1,11 +1,11 @@
 use std::iter::once;
 
-use hir::Semantics;
 use either::Either;
+use hir::{Semantics, TypeInfo};
 use ide_db::{RootDatabase, ty_filter::TryEnum};
 use syntax::{
     AstNode,
-    SyntaxKind::{FN, FOR_EXPR, LOOP_EXPR, WHILE_EXPR, WHITESPACE},
+    SyntaxKind::{CLOSURE_EXPR, FN, FOR_EXPR, LOOP_EXPR, WHILE_EXPR, WHITESPACE},
     SyntaxNode, T,
     ast::{
         self,
@@ -228,16 +228,26 @@ fn early_expression(
     parent_container: SyntaxNode,
     sema: &Semantics<'_, RootDatabase>,
 ) -> Option<ast::Expr> {
+    let return_none_expr = || {
+        let none_expr = make::expr_path(make::ext::ident_path("None"));
+        make::expr_return(Some(none_expr))
+    };
     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 none_expr = make::expr_path(make::ext::ident_path("None"));
-        return Some(make::expr_return(Some(none_expr)));
+        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)
+    {
+        return Some(return_none_expr());
     }
+
     Some(match parent_container.kind() {
         WHILE_EXPR | LOOP_EXPR | FOR_EXPR => make::expr_continue(None),
-        FN => make::expr_return(None),
+        FN | CLOSURE_EXPR => make::expr_return(None),
         _ => return None,
     })
 }
@@ -330,6 +340,40 @@ fn ret_option() -> Option<()> {
     }
 
     #[test]
+    fn convert_inside_closure() {
+        check_assist(
+            convert_to_guarded_return,
+            r#"
+fn main() {
+    let _f = || {
+        bar();
+        if$0 true {
+            foo();
+
+            // comment
+            bar();
+        }
+    }
+}
+"#,
+            r#"
+fn main() {
+    let _f = || {
+        bar();
+        if false {
+            return;
+        }
+        foo();
+
+        // comment
+        bar();
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
     fn convert_let_inside_fn() {
         check_assist(
             convert_to_guarded_return,