From f3ac64ac342fca3040e067a9e3c3c8aba9186860 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Dec 2024 17:23:12 -0800 Subject: [PATCH 1/5] Add test of closure vs jump precedence --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index fd6644d73c161..d545c017fdac5 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -70,6 +70,9 @@ static EXPRS: &[&str] = &[ // These mean different things. "return - 2", "(return) - 2", + // Closures and jumps have equal precedence. + "|| return break 2", + "return break (|| 2)", // FIXME: no parenthesis needed. // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", From 193d82797cfa88eb49d53c16745423de6bc54851 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Dec 2024 17:17:37 -0800 Subject: [PATCH 2/5] Squash closures and jumps into a single precedence level --- compiler/rustc_ast/src/ast.rs | 3 +-- compiler/rustc_ast/src/util/parser.rs | 3 +-- compiler/rustc_hir/src/hir.rs | 3 +-- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 14205f66491c5..2c9e55e007f9b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1317,9 +1317,8 @@ impl Expr { pub fn precedence(&self) -> ExprPrecedence { match self.kind { - ExprKind::Closure(..) => ExprPrecedence::Closure, - ExprKind::Break(..) + | ExprKind::Closure(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index e88bf27021aff..a4f152b46878f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -231,8 +231,7 @@ impl AssocOp { #[derive(Clone, Copy, PartialEq, PartialOrd)] pub enum ExprPrecedence { - Closure, - // return, break, yield + // return, break, yield, closures Jump, // = += -= *= /= %= &= |= ^= <<= >>= Assign, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a9696627f11b1..4524e1cbdf1fc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1697,9 +1697,8 @@ pub struct Expr<'hir> { impl Expr<'_> { pub fn precedence(&self) -> ExprPrecedence { match self.kind { - ExprKind::Closure { .. } => ExprPrecedence::Closure, - ExprKind::Break(..) + | ExprKind::Closure { .. } | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index d545c017fdac5..f535db06879f3 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -72,7 +72,7 @@ static EXPRS: &[&str] = &[ "(return) - 2", // Closures and jumps have equal precedence. "|| return break 2", - "return break (|| 2)", // FIXME: no parenthesis needed. + "return break || 2", // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", From 4df47a09a42620f018bdaed733fdbc4049a65e78 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Dec 2024 17:37:03 -0800 Subject: [PATCH 3/5] Add test of closure precedence with return type --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index f535db06879f3..6535367927ef0 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -73,6 +73,9 @@ static EXPRS: &[&str] = &[ // Closures and jumps have equal precedence. "|| return break 2", "return break || 2", + // Closures with a return type have especially high precedence. + "(|| -> T { x }) + 1", // FIXME: no parenthesis needed. + "(|| { x }) + 1", // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", From 72ac961616f23401c54f08436006250fd1fcdb9e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Dec 2024 17:41:47 -0800 Subject: [PATCH 4/5] Raise precedence of closure that has explicit return type --- compiler/rustc_ast/src/ast.rs | 10 ++++++++-- compiler/rustc_hir/src/hir.rs | 12 +++++++++--- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 2c9e55e007f9b..482efa132ab53 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1316,9 +1316,15 @@ impl Expr { } pub fn precedence(&self) -> ExprPrecedence { - match self.kind { + match &self.kind { + ExprKind::Closure(closure) => { + match closure.fn_decl.output { + FnRetTy::Default(_) => ExprPrecedence::Jump, + FnRetTy::Ty(_) => ExprPrecedence::Unambiguous, + } + } + ExprKind::Break(..) - | ExprKind::Closure(..) | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4524e1cbdf1fc..21fa11fbc0a66 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1696,9 +1696,15 @@ pub struct Expr<'hir> { impl Expr<'_> { pub fn precedence(&self) -> ExprPrecedence { - match self.kind { + match &self.kind { + ExprKind::Closure(closure) => { + match closure.fn_decl.output { + FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump, + FnRetTy::Return(_) => ExprPrecedence::Unambiguous, + } + } + ExprKind::Break(..) - | ExprKind::Closure { .. } | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) @@ -1741,7 +1747,7 @@ impl Expr<'_> { | ExprKind::Type(..) | ExprKind::Err(_) => ExprPrecedence::Unambiguous, - ExprKind::DropTemps(ref expr, ..) => expr.precedence(), + ExprKind::DropTemps(expr, ..) => expr.precedence(), } } diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 6535367927ef0..1f4e98d483d06 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -74,7 +74,7 @@ static EXPRS: &[&str] = &[ "|| return break 2", "return break || 2", // Closures with a return type have especially high precedence. - "(|| -> T { x }) + 1", // FIXME: no parenthesis needed. + "|| -> T { x } + 1", "(|| { x }) + 1", // These mean different things. "if let _ = true && false {}", From fe06c5dce1db564d42678ea8e4f4a8ae451fe4a3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Dec 2024 17:50:12 -0800 Subject: [PATCH 5/5] Never parenthesize `continue` --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 482efa132ab53..d7d4a821ef6a2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1325,7 +1325,6 @@ impl Expr { } ExprKind::Break(..) - | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) | ExprKind::Yeet(..) @@ -1359,6 +1358,7 @@ impl Expr { | ExprKind::Block(..) | ExprKind::Call(..) | ExprKind::ConstBlock(_) + | ExprKind::Continue(..) | ExprKind::Field(..) | ExprKind::ForLoop { .. } | ExprKind::FormatArgs(..) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 21fa11fbc0a66..2a7df6827e4dc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1705,7 +1705,6 @@ impl Expr<'_> { } ExprKind::Break(..) - | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::Yield(..) | ExprKind::Become(..) => ExprPrecedence::Jump, @@ -1731,6 +1730,7 @@ impl Expr<'_> { | ExprKind::Block(..) | ExprKind::Call(..) | ExprKind::ConstBlock(_) + | ExprKind::Continue(..) | ExprKind::Field(..) | ExprKind::If(..) | ExprKind::Index(..)