Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix formatting for ref_mut_iter_method_chain
Browse files Browse the repository at this point in the history
Jarcho committed Nov 14, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 453c07b commit 31dc4ab
Showing 2 changed files with 94 additions and 35 deletions.
7 changes: 4 additions & 3 deletions clippy_lints/src/methods/ref_mut_iter_method_chain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::{snippet_expr, TargetPrecedence};
use clippy_utils::source::{snippet_expr, ExprPosition};
use clippy_utils::ty::implements_trait;
use if_chain::if_chain;
use rustc_errors::Applicability;
@@ -17,7 +17,8 @@ pub(crate) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>) {
if implements_trait(cx, cx.typeck_results().expr_ty(base_expr).peel_refs(), iter_trait, &[]);
then {
let snip_expr = match base_expr.kind {
ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() && !base_expr.span.from_expansion()
ExprKind::Unary(UnOp::Deref, e)
if cx.typeck_results().expr_ty(e).is_ref() && !base_expr.span.from_expansion()
=> e,
_ => base_expr,
};
@@ -30,7 +31,7 @@ pub(crate) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>) {
"try",
format!(
"{}.by_ref()",
snippet_expr(cx, snip_expr, TargetPrecedence::Postfix, self_arg.span.ctxt(), &mut app),
snippet_expr(cx, snip_expr, ExprPosition::Postfix, self_arg.span.ctxt(), &mut app),
),
app,
);
122 changes: 90 additions & 32 deletions clippy_utils/src/source.rs
Original file line number Diff line number Diff line change
@@ -307,20 +307,34 @@ pub fn snippet_with_context(
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum TargetPrecedence {
Closure,
Assignment,
Range,
Or,
And,
Eq,
BitOr,
BitXor,
BitAnd,
Shift,
Add,
Mul,
As,
pub enum ExprPosition {
// Also includes `return`, `yield`, `break` and closures
Paren,
AssignmentRhs,
AssignmentLhs,
RangeLhs,
RangeRhs,
OrLhs,
OrRhs,
AndLhs,
AndRhs,
Let,
EqLhs,
EqRhs,
BitOrLhs,
BitOrRhs,
BitXorLhs,
BitXorRhs,
BitAndLhs,
BitAndRhs,
ShiftLhs,
ShiftRhs,
AddLhs,
AddRhs,
MulLhs,
MulRhs,
// Also includes type ascription
Cast,
Prefix,
Postfix,
}
@@ -345,7 +359,7 @@ pub enum TargetPrecedence {
pub fn snippet_expr(
cx: &LateContext<'_>,
expr: &Expr<'_>,
target_precedence: TargetPrecedence,
target_position: ExprPosition,
ctxt: SyntaxContext,
app: &mut Applicability,
) -> String {
@@ -355,29 +369,73 @@ pub fn snippet_expr(
Cow::Borrowed(snip) => snip.to_owned(),
Cow::Owned(snip) if is_mac_call => snip,
Cow::Owned(mut snip) => {
let needs_paren = match expr.kind {
let ctxt = expr.span.ctxt();

// Attempt to determine if parenthesis are needed base on the target position. The snippet may have
// parenthesis already, so attempt to find those.
// TODO: Remove parenthesis if they aren't needed at the target position.
let needs_paren = match expr.peel_drop_temps().kind {
ExprKind::Binary(_, lhs, rhs)
if (ctxt == lhs.span.ctxt() && expr.span.lo() != lhs.span.lo())
|| (ctxt == rhs.span.ctxt() && expr.span.hi() != rhs.span.hi()) =>
{
false
},
ExprKind::Binary(op, ..) => match op.node {
BinOpKind::Add | BinOpKind::Sub => target_precedence > TargetPrecedence::Add,
BinOpKind::Mul | BinOpKind::Div | BinOpKind::Rem => target_precedence > TargetPrecedence::Mul,
BinOpKind::And => target_precedence > TargetPrecedence::And,
BinOpKind::Or => target_precedence > TargetPrecedence::Or,
BinOpKind::BitXor => target_precedence > TargetPrecedence::BitXor,
BinOpKind::BitAnd => target_precedence > TargetPrecedence::BitAnd,
BinOpKind::BitOr => target_precedence > TargetPrecedence::BitOr,
BinOpKind::Shl | BinOpKind::Shr => target_precedence > TargetPrecedence::Shift,
BinOpKind::Add | BinOpKind::Sub => target_position > ExprPosition::AddLhs,
BinOpKind::Mul | BinOpKind::Div | BinOpKind::Rem => target_position > ExprPosition::MulLhs,
BinOpKind::And => target_position > ExprPosition::AndLhs,
BinOpKind::Or => target_position > ExprPosition::OrLhs,
BinOpKind::BitXor => target_position > ExprPosition::BitXorLhs,
BinOpKind::BitAnd => target_position > ExprPosition::BitAndLhs,
BinOpKind::BitOr => target_position > ExprPosition::BitOrLhs,
BinOpKind::Shl | BinOpKind::Shr => target_position > ExprPosition::ShiftLhs,
BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Gt | BinOpKind::Ge => {
target_precedence > TargetPrecedence::Eq
target_position > ExprPosition::EqLhs
},
},
ExprKind::Unary(..) | ExprKind::AddrOf(..) => target_precedence > TargetPrecedence::Prefix,
ExprKind::Cast(..) => target_precedence > TargetPrecedence::As,
ExprKind::Box(..)
| ExprKind::Closure(..)
ExprKind::Box(..) | ExprKind::Unary(..) | ExprKind::AddrOf(..) if snip.starts_with('(') => false,
ExprKind::Box(..) | ExprKind::Unary(..) | ExprKind::AddrOf(..) => {
target_position > ExprPosition::Prefix
},
ExprKind::Let(..) if snip.starts_with('(') => false,
ExprKind::Let(..) => target_position > ExprPosition::Let,
ExprKind::Cast(lhs, rhs)
if (ctxt == lhs.span.ctxt() && expr.span.lo() != lhs.span.lo())
|| (ctxt == rhs.span.ctxt() && expr.span.hi() != rhs.span.hi()) =>
{
false
},
ExprKind::Cast(..) | ExprKind::Type(..) => target_position > ExprPosition::Cast,

ExprKind::Closure(..)
| ExprKind::Break(..)
| ExprKind::Ret(..)
| ExprKind::Yield(..) => target_precedence > TargetPrecedence::Closure,
ExprKind::Assign(..) | ExprKind::AssignOp(..) => target_precedence > TargetPrecedence::Assignment,
_ => false,
| ExprKind::Yield(..)
| ExprKind::Assign(..)
| ExprKind::AssignOp(..) => target_position > ExprPosition::AssignmentRhs,

// Postfix operators, or expression with braces of some form
ExprKind::Array(_)
| ExprKind::Call(..)
| ExprKind::ConstBlock(_)
| ExprKind::MethodCall(..)
| ExprKind::Tup(..)
| ExprKind::Lit(..)
| ExprKind::DropTemps(_)
| ExprKind::If(..)
| ExprKind::Loop(..)
| ExprKind::Match(..)
| ExprKind::Block(..)
| ExprKind::Field(..)
| ExprKind::Index(..)
| ExprKind::Path(_)
| ExprKind::Continue(_)
| ExprKind::InlineAsm(_)
| ExprKind::LlvmInlineAsm(_)
| ExprKind::Struct(..)
| ExprKind::Repeat(..)
| ExprKind::Err => false,
};

if needs_paren {

0 comments on commit 31dc4ab

Please sign in to comment.