Skip to content
/ rust Public
forked from rust-lang/rust

Commit 44a8d96

Browse files
authored
Rollup merge of rust-lang#133140 - dtolnay:precedence, r=fmease
Inline ExprPrecedence::order into Expr::precedence The representation of expression precedence in rustc_ast has been an obstacle to further improvements in the pretty-printer (continuing from rust-lang#119105 and rust-lang#119427). Previously the operation of *"does this expression have lower precedence than that one"* (relevant for parenthesis insertion in macro-generated syntax trees) consisted of 3 steps: 1. Convert `Expr` to `ExprPrecedence` using `.precedence()` 2. Convert `ExprPrecedence` to `i8` using `.order()` 3. Compare using `<` As far as I can guess, the reason for the separation between `precedence()` and `order()` was so that both `rustc_ast::Expr` and `rustc_hir::Expr` could convert as straightforwardly as possible to the same `ExprPrecedence` enum, and then the more finicky logic performed by `order` could be present just once. The mapping between `Expr` and `ExprPrecedence` was intended to be as straightforward as possible: ```rust match self.kind { ExprKind::Closure(..) => ExprPrecedence::Closure, ... } ``` although there were exceptions of both many-to-one, and one-to-many: ```rust ExprKind::Underscore => ExprPrecedence::Path, ExprKind::Path(..) => ExprPrecedence::Path, ... ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match, ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch, ``` Where the nature of `ExprPrecedence` becomes problematic is when a single expression kind might be associated with multiple different precedence levels depending on context (outside the expression) and contents (inside the expression). For example consider what is the precedence of an ExprKind::Closure `$closure`. Well, on the left-hand side of a binary operator it would need parentheses in order to avoid the trailing binary operator being absorbed into the closure body: `($closure) + Rhs`, so the precedence is something lower than that of `+`. But on the right-hand side of a binary operator, a closure is just a straightforward prefix expression like a unary op, which is a relatively high precedence level, higher than binops but lower than method calls: `Lhs + $closure` is fine without parens but `($closure).method()` needs them. But as a third case, if the closure contains an explicit return type, then the precedence is an even higher level than that, never needing parenthesization even in a binop left-hand side or method call: `|| -> bool { false } + Rhs` or `|| -> bool { false }.method()`. You can see that trying to capture all of this resolution about expressions into `ExprPrecedence` violates the intention of `ExprPrecedence` being a straightforward one-to-one correspondence from each AST and HIR `ExprKind` variant. It would be possible to attempt that by doing stuff like `ExprPrecedence::Closure(Side::Leading, ReturnType::No)`, but I don't foresee the original envisioned benefit of the `precedence()`/`order()` distinction being retained in this approach. Instead I want to move toward a model that Syn has been using successfully. In Syn, there is a Precedence enum but it differs from rustc in the following ways: - There are [relatively few variants](https://github.com/dtolnay/syn/blob/2.0.87/src/precedence.rs#L11-L47) compared to rustc's `ExprPrecedence`. For example there is no distinction at the precedence level between returns and closures, or between loops and method calls. - We distinguish between [leading](https://github.com/dtolnay/syn/blob/2.0.87/src/fixup.rs#L293) and [trailing](https://github.com/dtolnay/syn/blob/2.0.87/src/fixup.rs#L309) precedence, taking into account an expression's context such as what token follows it (for various syntactic bail-outs in Rust's grammar, like ambiguities around break-with-value) and how it relates to operators from the surrounding syntax tree. - There are no hardcoded mysterious integer quantities like rustc's `PREC_CLOSURE = -40`. All precedence comparisons are performed via PartialOrd on a C-like enum. This PR is just a first step in these changes. As you can tell from Syn, I definitely think there is value in having a dedicated type to represent precedence, instead of what `order()` is doing with `i8`. But that is a whole separate adventure because rustc_ast doesn't even agree consistently on `i8` being the type for precedence order; `AssocOp::precedence` instead uses `usize` and there are casts in both directions. It is likely that a type called `ExprPrecedence` will re-appear, but it will look substantially different from the one that existed before this PR.
2 parents 5281f76 + e5f1555 commit 44a8d96

File tree

16 files changed

+146
-225
lines changed

16 files changed

+146
-225
lines changed

compiler/rustc_ast/src/ast.rs

+66-46
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ pub use crate::format::*;
3939
use crate::ptr::P;
4040
use crate::token::{self, CommentKind, Delimiter};
4141
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
42-
pub use crate::util::parser::ExprPrecedence;
42+
use crate::util::parser::{
43+
AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS,
44+
};
4345

4446
/// A "Label" is an identifier of some point in sources,
4547
/// e.g. in the following code:
@@ -1314,53 +1316,71 @@ impl Expr {
13141316
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
13151317
}
13161318

1317-
pub fn precedence(&self) -> ExprPrecedence {
1319+
pub fn precedence(&self) -> i8 {
13181320
match self.kind {
1319-
ExprKind::Array(_) => ExprPrecedence::Array,
1320-
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
1321-
ExprKind::Call(..) => ExprPrecedence::Call,
1322-
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
1323-
ExprKind::Tup(_) => ExprPrecedence::Tup,
1324-
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
1325-
ExprKind::Unary(..) => ExprPrecedence::Unary,
1326-
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
1327-
ExprKind::Cast(..) => ExprPrecedence::Cast,
1328-
ExprKind::Let(..) => ExprPrecedence::Let,
1329-
ExprKind::If(..) => ExprPrecedence::If,
1330-
ExprKind::While(..) => ExprPrecedence::While,
1331-
ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
1332-
ExprKind::Loop(..) => ExprPrecedence::Loop,
1333-
ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
1334-
ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
1335-
ExprKind::Closure(..) => ExprPrecedence::Closure,
1336-
ExprKind::Block(..) => ExprPrecedence::Block,
1337-
ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
1338-
ExprKind::Gen(..) => ExprPrecedence::Gen,
1339-
ExprKind::Await(..) => ExprPrecedence::Await,
1340-
ExprKind::Assign(..) => ExprPrecedence::Assign,
1341-
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
1342-
ExprKind::Field(..) => ExprPrecedence::Field,
1343-
ExprKind::Index(..) => ExprPrecedence::Index,
1344-
ExprKind::Range(..) => ExprPrecedence::Range,
1345-
ExprKind::Underscore => ExprPrecedence::Path,
1346-
ExprKind::Path(..) => ExprPrecedence::Path,
1347-
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
1348-
ExprKind::Break(..) => ExprPrecedence::Break,
1349-
ExprKind::Continue(..) => ExprPrecedence::Continue,
1350-
ExprKind::Ret(..) => ExprPrecedence::Ret,
1351-
ExprKind::Struct(..) => ExprPrecedence::Struct,
1352-
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
1353-
ExprKind::Paren(..) => ExprPrecedence::Paren,
1354-
ExprKind::Try(..) => ExprPrecedence::Try,
1355-
ExprKind::Yield(..) => ExprPrecedence::Yield,
1356-
ExprKind::Yeet(..) => ExprPrecedence::Yeet,
1357-
ExprKind::Become(..) => ExprPrecedence::Become,
1358-
ExprKind::InlineAsm(..)
1359-
| ExprKind::Type(..)
1360-
| ExprKind::OffsetOf(..)
1321+
ExprKind::Closure(..) => PREC_CLOSURE,
1322+
1323+
ExprKind::Break(..)
1324+
| ExprKind::Continue(..)
1325+
| ExprKind::Ret(..)
1326+
| ExprKind::Yield(..)
1327+
| ExprKind::Yeet(..)
1328+
| ExprKind::Become(..) => PREC_JUMP,
1329+
1330+
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
1331+
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
1332+
// ensures that `pprust` will add parentheses in the right places to get the desired
1333+
// parse.
1334+
ExprKind::Range(..) => PREC_RANGE,
1335+
1336+
// Binop-like expr kinds, handled by `AssocOp`.
1337+
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
1338+
ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
1339+
1340+
ExprKind::Assign(..) |
1341+
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
1342+
1343+
// Unary, prefix
1344+
ExprKind::AddrOf(..)
1345+
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
1346+
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
1347+
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
1348+
// but we need to print `(let _ = a) < b` as-is with parens.
1349+
| ExprKind::Let(..)
1350+
| ExprKind::Unary(..) => PREC_PREFIX,
1351+
1352+
// Never need parens
1353+
ExprKind::Array(_)
1354+
| ExprKind::Await(..)
1355+
| ExprKind::Block(..)
1356+
| ExprKind::Call(..)
1357+
| ExprKind::ConstBlock(_)
1358+
| ExprKind::Field(..)
1359+
| ExprKind::ForLoop { .. }
13611360
| ExprKind::FormatArgs(..)
1362-
| ExprKind::MacCall(..) => ExprPrecedence::Mac,
1363-
ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
1361+
| ExprKind::Gen(..)
1362+
| ExprKind::If(..)
1363+
| ExprKind::IncludedBytes(..)
1364+
| ExprKind::Index(..)
1365+
| ExprKind::InlineAsm(..)
1366+
| ExprKind::Lit(_)
1367+
| ExprKind::Loop(..)
1368+
| ExprKind::MacCall(..)
1369+
| ExprKind::Match(..)
1370+
| ExprKind::MethodCall(..)
1371+
| ExprKind::OffsetOf(..)
1372+
| ExprKind::Paren(..)
1373+
| ExprKind::Path(..)
1374+
| ExprKind::Repeat(..)
1375+
| ExprKind::Struct(..)
1376+
| ExprKind::Try(..)
1377+
| ExprKind::TryBlock(..)
1378+
| ExprKind::Tup(_)
1379+
| ExprKind::Type(..)
1380+
| ExprKind::Underscore
1381+
| ExprKind::While(..)
1382+
| ExprKind::Err(_)
1383+
| ExprKind::Dummy => PREC_UNAMBIGUOUS,
13641384
}
13651385
}
13661386

compiler/rustc_ast/src/util/parser.rs

-115
Original file line numberDiff line numberDiff line change
@@ -237,121 +237,6 @@ pub const PREC_PREFIX: i8 = 50;
237237
pub const PREC_UNAMBIGUOUS: i8 = 60;
238238
pub const PREC_FORCE_PAREN: i8 = 100;
239239

240-
#[derive(Debug, Clone, Copy)]
241-
pub enum ExprPrecedence {
242-
Closure,
243-
Break,
244-
Continue,
245-
Ret,
246-
Yield,
247-
Yeet,
248-
Become,
249-
250-
Range,
251-
252-
Binary(BinOpKind),
253-
254-
Cast,
255-
256-
Assign,
257-
AssignOp,
258-
259-
AddrOf,
260-
Let,
261-
Unary,
262-
263-
Call,
264-
MethodCall,
265-
Field,
266-
Index,
267-
Try,
268-
Mac,
269-
270-
Array,
271-
Repeat,
272-
Tup,
273-
Lit,
274-
Path,
275-
Paren,
276-
If,
277-
While,
278-
ForLoop,
279-
Loop,
280-
Match,
281-
PostfixMatch,
282-
ConstBlock,
283-
Block,
284-
TryBlock,
285-
Struct,
286-
Gen,
287-
Await,
288-
Err,
289-
}
290-
291-
impl ExprPrecedence {
292-
pub fn order(self) -> i8 {
293-
match self {
294-
ExprPrecedence::Closure => PREC_CLOSURE,
295-
296-
ExprPrecedence::Break
297-
| ExprPrecedence::Continue
298-
| ExprPrecedence::Ret
299-
| ExprPrecedence::Yield
300-
| ExprPrecedence::Yeet
301-
| ExprPrecedence::Become => PREC_JUMP,
302-
303-
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
304-
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
305-
// ensures that `pprust` will add parentheses in the right places to get the desired
306-
// parse.
307-
ExprPrecedence::Range => PREC_RANGE,
308-
309-
// Binop-like expr kinds, handled by `AssocOp`.
310-
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
311-
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
312-
313-
ExprPrecedence::Assign |
314-
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
315-
316-
// Unary, prefix
317-
ExprPrecedence::AddrOf
318-
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
319-
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
320-
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
321-
// but we need to print `(let _ = a) < b` as-is with parens.
322-
| ExprPrecedence::Let
323-
| ExprPrecedence::Unary => PREC_PREFIX,
324-
325-
// Never need parens
326-
ExprPrecedence::Array
327-
| ExprPrecedence::Await
328-
| ExprPrecedence::Block
329-
| ExprPrecedence::Call
330-
| ExprPrecedence::ConstBlock
331-
| ExprPrecedence::Field
332-
| ExprPrecedence::ForLoop
333-
| ExprPrecedence::Gen
334-
| ExprPrecedence::If
335-
| ExprPrecedence::Index
336-
| ExprPrecedence::Lit
337-
| ExprPrecedence::Loop
338-
| ExprPrecedence::Mac
339-
| ExprPrecedence::Match
340-
| ExprPrecedence::MethodCall
341-
| ExprPrecedence::Paren
342-
| ExprPrecedence::Path
343-
| ExprPrecedence::PostfixMatch
344-
| ExprPrecedence::Repeat
345-
| ExprPrecedence::Struct
346-
| ExprPrecedence::Try
347-
| ExprPrecedence::TryBlock
348-
| ExprPrecedence::Tup
349-
| ExprPrecedence::While
350-
| ExprPrecedence::Err => PREC_UNAMBIGUOUS,
351-
}
352-
}
353-
}
354-
355240
/// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`.
356241
pub fn prec_let_scrutinee_needs_par() -> usize {
357242
AssocOp::LAnd.precedence()

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl<'a> State<'a> {
5959
}
6060

6161
fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8, fixup: FixupContext) {
62-
self.print_expr_cond_paren(expr, expr.precedence().order() < prec, fixup);
62+
self.print_expr_cond_paren(expr, expr.precedence() < prec, fixup);
6363
}
6464

6565
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
@@ -615,7 +615,7 @@ impl<'a> State<'a> {
615615
expr,
616616
// Parenthesize if required by precedence, or in the
617617
// case of `break 'inner: loop { break 'inner 1 } + 1`
618-
expr.precedence().order() < parser::PREC_JUMP
618+
expr.precedence() < parser::PREC_JUMP
619619
|| (opt_label.is_none() && classify::leading_labeled_expr(expr)),
620620
fixup.subsequent_subexpression(),
621621
);

compiler/rustc_ast_pretty/src/pprust/state/fixup.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,6 @@ impl FixupContext {
191191
/// "let chain".
192192
pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
193193
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
194-
|| parser::needs_par_as_let_scrutinee(expr.precedence().order())
194+
|| parser::needs_par_as_let_scrutinee(expr.precedence())
195195
}
196196
}

compiler/rustc_hir/src/hir.rs

+47-34
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt;
22

33
use rustc_abi::ExternAbi;
4-
use rustc_ast::util::parser::ExprPrecedence;
4+
use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS};
55
use rustc_ast::{
66
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
77
LitKind, TraitObjectSyntax, UintTy,
@@ -1717,41 +1717,54 @@ pub struct Expr<'hir> {
17171717
}
17181718

17191719
impl Expr<'_> {
1720-
pub fn precedence(&self) -> ExprPrecedence {
1720+
pub fn precedence(&self) -> i8 {
17211721
match self.kind {
1722-
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
1723-
ExprKind::Array(_) => ExprPrecedence::Array,
1724-
ExprKind::Call(..) => ExprPrecedence::Call,
1725-
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
1726-
ExprKind::Tup(_) => ExprPrecedence::Tup,
1727-
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
1728-
ExprKind::Unary(..) => ExprPrecedence::Unary,
1729-
ExprKind::Lit(_) => ExprPrecedence::Lit,
1730-
ExprKind::Cast(..) => ExprPrecedence::Cast,
1722+
ExprKind::Closure { .. } => PREC_CLOSURE,
1723+
1724+
ExprKind::Break(..)
1725+
| ExprKind::Continue(..)
1726+
| ExprKind::Ret(..)
1727+
| ExprKind::Yield(..)
1728+
| ExprKind::Become(..) => PREC_JUMP,
1729+
1730+
// Binop-like expr kinds, handled by `AssocOp`.
1731+
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
1732+
ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
1733+
1734+
ExprKind::Assign(..) |
1735+
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
1736+
1737+
// Unary, prefix
1738+
ExprKind::AddrOf(..)
1739+
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
1740+
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
1741+
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
1742+
// but we need to print `(let _ = a) < b` as-is with parens.
1743+
| ExprKind::Let(..)
1744+
| ExprKind::Unary(..) => PREC_PREFIX,
1745+
1746+
// Never need parens
1747+
ExprKind::Array(_)
1748+
| ExprKind::Block(..)
1749+
| ExprKind::Call(..)
1750+
| ExprKind::ConstBlock(_)
1751+
| ExprKind::Field(..)
1752+
| ExprKind::If(..)
1753+
| ExprKind::Index(..)
1754+
| ExprKind::InlineAsm(..)
1755+
| ExprKind::Lit(_)
1756+
| ExprKind::Loop(..)
1757+
| ExprKind::Match(..)
1758+
| ExprKind::MethodCall(..)
1759+
| ExprKind::OffsetOf(..)
1760+
| ExprKind::Path(..)
1761+
| ExprKind::Repeat(..)
1762+
| ExprKind::Struct(..)
1763+
| ExprKind::Tup(_)
1764+
| ExprKind::Type(..)
1765+
| ExprKind::Err(_) => PREC_UNAMBIGUOUS,
1766+
17311767
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
1732-
ExprKind::If(..) => ExprPrecedence::If,
1733-
ExprKind::Let(..) => ExprPrecedence::Let,
1734-
ExprKind::Loop(..) => ExprPrecedence::Loop,
1735-
ExprKind::Match(..) => ExprPrecedence::Match,
1736-
ExprKind::Closure { .. } => ExprPrecedence::Closure,
1737-
ExprKind::Block(..) => ExprPrecedence::Block,
1738-
ExprKind::Assign(..) => ExprPrecedence::Assign,
1739-
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
1740-
ExprKind::Field(..) => ExprPrecedence::Field,
1741-
ExprKind::Index(..) => ExprPrecedence::Index,
1742-
ExprKind::Path(..) => ExprPrecedence::Path,
1743-
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
1744-
ExprKind::Break(..) => ExprPrecedence::Break,
1745-
ExprKind::Continue(..) => ExprPrecedence::Continue,
1746-
ExprKind::Ret(..) => ExprPrecedence::Ret,
1747-
ExprKind::Become(..) => ExprPrecedence::Become,
1748-
ExprKind::Struct(..) => ExprPrecedence::Struct,
1749-
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
1750-
ExprKind::Yield(..) => ExprPrecedence::Yield,
1751-
ExprKind::Type(..) | ExprKind::InlineAsm(..) | ExprKind::OffsetOf(..) => {
1752-
ExprPrecedence::Mac
1753-
}
1754-
ExprKind::Err(_) => ExprPrecedence::Err,
17551768
}
17561769
}
17571770

compiler/rustc_hir_pretty/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ impl<'a> State<'a> {
10111011
}
10121012

10131013
fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) {
1014-
self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
1014+
self.print_expr_cond_paren(expr, expr.precedence() < prec)
10151015
}
10161016

10171017
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
@@ -1045,7 +1045,7 @@ impl<'a> State<'a> {
10451045
}
10461046
self.space();
10471047
self.word_space("=");
1048-
let npals = || parser::needs_par_as_let_scrutinee(init.precedence().order());
1048+
let npals = || parser::needs_par_as_let_scrutinee(init.precedence());
10491049
self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals())
10501050
}
10511051

compiler/rustc_hir_typeck/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
606606
};
607607

608608
if let Ok(rest_snippet) = rest_snippet {
609-
let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS {
609+
let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS {
610610
vec![
611611
(up_to_rcvr_span, "".to_string()),
612612
(rest_span, format!(".{}({rest_snippet}", segment.ident)),

0 commit comments

Comments
 (0)