Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #5624 #5904

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

GambitingMan
Copy link
Contributor

Fixes #5624. The output seems to follow the style guide for closures without any additional effort.

@calebcartwright
Copy link
Member

Thanks for the PR @GambitingMan!

@ytmimi since you'd commented on the link issue, do you still have enough mental context on it to remember whether this could introduce formatting changes/need to be version gated to maintain stability in any other contexts?

@ytmimi
Copy link
Contributor

ytmimi commented Sep 8, 2023

@calebcartwright are there contexts outside of closures that you're worried about?

This could have an impact anywhere a closures can be used because the old behavior was to return None from rewrite_closure_expr leaving the code unformatted. The change is limited to what I assume is a fairly rare case; closures who's body is a single binary expression, where the lhs and rhs are any of the following (optionally used with unary, try, or reference operators or cast expressions):

  • ast::ExprKind::Match(..)
  • ast::ExprKind::Async(..)
  • ast::ExprKind::Block(..)
  • ast::ExprKind::TryBlock(..)
  • ast::ExprKind::Loop(..)
  • ast::ExprKind::Struct(..)
  • ast::ExprKind::Binary(..) <--- recursive case

For example, This PR enables the following to reformat the same binary expression closure who's lhs and rhs are themselves binary expressions in a few different contexts (function arguments, let binding, struct field):

fn main() {
    f(||
        {
            let a =1;
            a
         } + { 2 } + {
            let b = 3;
            b
         } + { 4 }
    );

   let c = ||
        {
            let d =1;
            d
         } + { 2 } + {
            let e = 3;
            e
         } + { 4 };

    let f = MyStruct {
        field: ||
        {
            let g =1;
            g
         } + { 2 } + {
            let h = 3;
            h
         } + { 4 }
    };
}

output:

fn main() {
    f(|| {
        let a = 1;
        a
    } + { 2 }
        + {
            let b = 3;
            b
        }
        + { 4 });

    let c = || {
        let d = 1;
        d
    } + { 2 }
        + {
            let e = 3;
            e
        }
        + { 4 };

    let f = MyStruct {
        field: || {
            let g = 1;
            g
        } + { 2 }
            + {
                let h = 3;
                h
            }
            + { 4 },
    };
}

Here's the diff:

Diff in <stdin> at line 1:
 fn main() {
-    f(||
-        {
-            let a =1;
-            a
-         } + { 2 } + {
+    f(|| {
+        let a = 1;
+        a
+    } + { 2 }
+        + {
             let b = 3;
             b
-         } + { 4 }
-    );
+        }
+        + { 4 });
 
-   let c = ||
-        {
-            let d =1;
-            d
-         } + { 2 } + {
+    let c = || {
+        let d = 1;
+        d
+    } + { 2 }
+        + {
             let e = 3;
             e
-         } + { 4 };
+        }
+        + { 4 };
 
     let f = MyStruct {
-        field: ||
-        {
-            let g =1;
+        field: || {
+            let g = 1;
             g
-         } + { 2 } + {
-            let h = 3;
-            h
-         } + { 4 }
+        } + { 2 }
+            + {
+                let h = 3;
+                h
+            }
+            + { 4 },
     };
 }

@ytmimi
Copy link
Contributor

ytmimi commented Sep 8, 2023

Might be safer to gate this on Version::Two, but in the meantime I just kicked off the diff check job to see if the PR as currently implemented impacts any of the repos we're testing against.

@ytmimi
Copy link
Contributor

ytmimi commented Sep 8, 2023

For what it's worth, the diff check job passed ✅

@GambitingMan
Copy link
Contributor Author

I added a check for version two, though it unfortunately changes the signature of the allow_multi_line function, since it requires the context. I also couldn't make the function a closure instead, as it is recursive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Back-to-back match blocks causes error[internal]: left behind trailing whitespace
4 participants