about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs28
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/fixup.rs14
-rw-r--r--tests/ui-fulldeps/pprust-parenthesis-insertion.rs4
3 files changed, 33 insertions, 13 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index dce76fb1e77..ab1dd46fe33 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -245,19 +245,21 @@ impl<'a> State<'a> {
         base_args: &[P<ast::Expr>],
         fixup: FixupContext,
     ) {
-        // Unlike in `print_expr_call`, no change to fixup here because
+        // The fixup here is different than in `print_expr_call` because
         // statement boundaries never occur in front of a `.` (or `?`) token.
         //
-        //     match () { _ => f }.method();
+        // Needs parens:
+        //
+        //     (loop { break x; })();
+        //
+        // Does not need parens:
+        //
+        //     loop { break x; }.method();
         //
-        // Parenthesizing only for precedence and not with regard to statement
-        // boundaries, `$receiver.method()` can be parsed back as a statement
-        // containing an expression if and only if `$receiver` can be parsed as
-        // a statement containing an expression.
         self.print_expr_cond_paren(
             receiver,
             receiver.precedence() < ExprPrecedence::Unambiguous,
-            fixup,
+            fixup.leftmost_subexpression_with_dot(),
         );
 
         self.word(".");
@@ -503,7 +505,7 @@ impl<'a> State<'a> {
                         self.print_expr_cond_paren(
                             expr,
                             expr.precedence() < ExprPrecedence::Unambiguous,
-                            fixup,
+                            fixup.leftmost_subexpression_with_dot(),
                         );
                         self.word_nbsp(".match");
                     }
@@ -567,7 +569,7 @@ impl<'a> State<'a> {
                 self.print_expr_cond_paren(
                     expr,
                     expr.precedence() < ExprPrecedence::Unambiguous,
-                    fixup,
+                    fixup.leftmost_subexpression_with_dot(),
                 );
                 self.word(".await");
             }
@@ -606,7 +608,7 @@ impl<'a> State<'a> {
                 self.print_expr_cond_paren(
                     expr,
                     expr.precedence() < ExprPrecedence::Unambiguous,
-                    fixup,
+                    fixup.leftmost_subexpression_with_dot(),
                 );
                 self.word(".");
                 self.print_ident(*ident);
@@ -763,7 +765,11 @@ impl<'a> State<'a> {
                 }
             }
             ast::ExprKind::Try(e) => {
-                self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup);
+                self.print_expr_cond_paren(
+                    e,
+                    e.precedence() < ExprPrecedence::Unambiguous,
+                    fixup.leftmost_subexpression_with_dot(),
+                );
                 self.word("?")
             }
             ast::ExprKind::TryBlock(blk) => {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
index ff466703f73..3ef21f5cb29 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs
@@ -138,6 +138,20 @@ impl FixupContext {
         }
     }
 
+    /// Transform this fixup into the one that should apply when printing a
+    /// leftmost subexpression followed by a `.` or `?` token, which confer
+    /// different statement boundary rules compared to other leftmost
+    /// subexpressions.
+    pub(crate) fn leftmost_subexpression_with_dot(self) -> Self {
+        FixupContext {
+            stmt: self.stmt || self.leftmost_subexpression_in_stmt,
+            leftmost_subexpression_in_stmt: false,
+            match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm,
+            leftmost_subexpression_in_match_arm: false,
+            ..self
+        }
+    }
+
     /// Transform this fixup into the one that should apply when printing any
     /// subexpression that is neither a leftmost subexpression nor surrounded in
     /// delimiters.
diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs
index 8cef9fa13f9..dc45731dce7 100644
--- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs
+++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs
@@ -110,8 +110,8 @@ static EXPRS: &[&str] = &[
     "{ (loop {}) - 1 }",
     "match 2 { _ => (loop {}) - 1 }",
     // No eager statement boundary if followed by `.` or `?`.
-    "{ (loop {}).to_string() - 1 }",  // FIXME: no parenthesis needed.
-    "match 2 { _ => (loop {}).to_string() - 1 }",  // FIXME: no parenthesis needed.
+    "{ loop {}.to_string() - 1 }",
+    "match 2 { _ => loop {}.to_string() - 1 }",
     // Angle bracket is eagerly parsed as a path's generic argument list.
     "(2 as T) < U",
     "(2 as T<U>) < V", // FIXME: no parentheses needed.