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 signed with the committer’s verified signature. The key has expired.
vespian Paweł Rozlach
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.