Fix prefix adjustment hints unnecessarily introducing parens

This commit is contained in:
Lukas Wirth 2025-02-28 09:45:24 +01:00
parent 505b52da5f
commit f655062cb0
2 changed files with 23 additions and 12 deletions

View File

@ -260,7 +260,7 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool,
if postfix { if postfix {
// postfix ops have higher precedence than any other operator, so we need to wrap // postfix ops have higher precedence than any other operator, so we need to wrap
// any inner expression that is below (except for jumps if they don't have a value) // any inner expression that is below (except for jumps if they don't have a value)
let needs_inner_parens = prec < ExprPrecedence::Unambiguous && { let needs_inner_parens = prec < ExprPrecedence::Postfix && {
prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value() prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value()
}; };
// given we are the higher precedence, no parent expression will have stronger requirements // given we are the higher precedence, no parent expression will have stronger requirements
@ -276,9 +276,12 @@ fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool,
// if we are already wrapped, great, no need to wrap again // if we are already wrapped, great, no need to wrap again
.filter(|it| !matches!(it, ast::Expr::ParenExpr(_))) .filter(|it| !matches!(it, ast::Expr::ParenExpr(_)))
.map(|it| it.precedence()); .map(|it| it.precedence());
// if we have no parent, we don't need outer parens to disambiguate // if we have no parent, we don't need outer parens to disambiguate
// otherwise anything with higher precedence than what we insert needs to wrap us // otherwise anything with higher precedence than what we insert needs to wrap us
let needs_outer_parens = parent.is_some_and(|prec| prec > ExprPrecedence::Prefix); // that means only postfix ops
let needs_outer_parens =
parent.is_some_and(|parent_prec| parent_prec == ExprPrecedence::Postfix);
(needs_outer_parens, needs_inner_parens) (needs_outer_parens, needs_inner_parens)
} }
} }
@ -291,7 +294,7 @@ mod tests {
}; };
#[test] #[test]
fn adjustment_hints() { fn adjustment_hints_prefix() {
check_with_config( check_with_config(
InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG }, InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
r#" r#"
@ -381,6 +384,8 @@ fn main() {
&mut Struct[0]; &mut Struct[0];
//^^^^^^(&mut $ //^^^^^^(&mut $
//^^^^^^) //^^^^^^)
let _: (&mut (),) = (&mut (),);
//^^^^^^^&mut *
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -472,6 +477,9 @@ fn main() {
//^^^^^^.& //^^^^^^.&
&mut Struct[0]; &mut Struct[0];
//^^^^^^.&mut //^^^^^^.&mut
let _: (&mut (),) = (&mut (),);
//^^^^^^^(
//^^^^^^^).*.&mut
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]

View File

@ -35,7 +35,9 @@ pub enum ExprPrecedence {
Cast, Cast,
// unary - * ! & &mut // unary - * ! & &mut
Prefix, Prefix,
// paths, loops, function calls, array indexing, field expressions, method calls // function calls, array indexing, field expressions, method calls
Postfix,
// paths, loops,
Unambiguous, Unambiguous,
} }
@ -57,6 +59,7 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence {
}, },
Expr::BreakExpr(_) Expr::BreakExpr(_)
| Expr::BecomeExpr(_)
| Expr::ContinueExpr(_) | Expr::ContinueExpr(_)
| Expr::ReturnExpr(_) | Expr::ReturnExpr(_)
| Expr::YeetExpr(_) | Expr::YeetExpr(_)
@ -89,27 +92,27 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence {
Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix, Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix,
Expr::ArrayExpr(_) Expr::AwaitExpr(_)
| Expr::AsmExpr(_)
| Expr::AwaitExpr(_)
| Expr::BecomeExpr(_)
| Expr::BlockExpr(_)
| Expr::CallExpr(_) | Expr::CallExpr(_)
| Expr::FieldExpr(_) | Expr::FieldExpr(_)
| Expr::IndexExpr(_)
| Expr::MethodCallExpr(_)
| Expr::TryExpr(_) => ExprPrecedence::Postfix,
Expr::ArrayExpr(_)
| Expr::AsmExpr(_)
| Expr::BlockExpr(_)
| Expr::ForExpr(_) | Expr::ForExpr(_)
| Expr::FormatArgsExpr(_) | Expr::FormatArgsExpr(_)
| Expr::IfExpr(_) | Expr::IfExpr(_)
| Expr::IndexExpr(_)
| Expr::Literal(_) | Expr::Literal(_)
| Expr::LoopExpr(_) | Expr::LoopExpr(_)
| Expr::MacroExpr(_) | Expr::MacroExpr(_)
| Expr::MatchExpr(_) | Expr::MatchExpr(_)
| Expr::MethodCallExpr(_)
| Expr::OffsetOfExpr(_) | Expr::OffsetOfExpr(_)
| Expr::ParenExpr(_) | Expr::ParenExpr(_)
| Expr::PathExpr(_) | Expr::PathExpr(_)
| Expr::RecordExpr(_) | Expr::RecordExpr(_)
| Expr::TryExpr(_)
| Expr::TupleExpr(_) | Expr::TupleExpr(_)
| Expr::UnderscoreExpr(_) | Expr::UnderscoreExpr(_)
| Expr::WhileExpr(_) => ExprPrecedence::Unambiguous, | Expr::WhileExpr(_) => ExprPrecedence::Unambiguous,