-use crate::utils::ast_utils::{eq_id, is_useless_with_eq_exprs, IdentIter};
-use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
+use clippy_utils::ast_utils::{eq_id, is_useless_with_eq_exprs, IdentIter};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
use core::ops::{Add, AddAssign};
use if_chain::if_chain;
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, StmtKind};
use rustc_span::Span;
declare_clippy_lint! {
- /// **What it does:**
+ /// ### What it does
/// Checks for unlikely usages of binary operators that are almost
/// certainly typos and/or copy/paste errors, given the other usages
/// of binary operators nearby.
- /// **Why is this bad?**
+ ///
+ /// ### Why is this bad?
/// They are probably bugs and if they aren't then they look like bugs
/// and you should add a comment explaining why you are doing such an
/// odd set of operations.
- /// **Known problems:**
+ ///
+ /// ### Known problems
/// There may be some false positives if you are trying to do something
/// unusual that happens to look like a typo.
///
- /// **Example:**
- ///
+ /// ### Example
/// ```rust
/// struct Vec3 {
/// x: f64,
/// }
/// }
/// ```
+ #[clippy::version = "1.50.0"]
pub SUSPICIOUS_OPERATION_GROUPINGS,
- style,
+ nursery,
"groupings of binary operations that look suspiciously like typos"
}
i: usize,
expected_loc: IdentLocation,
) {
- if let Some(binop) = binops.get(i).cloned() {
+ if let Some(binop) = binops.get(i).copied() {
// We need to try and figure out which identifier we should
// suggest using instead. Since there could be multiple
// replacement candidates in a given expression, and we're
emit_suggestion(
cx,
binop.span,
- replace_left_sugg(cx, &binop, &sugg, &mut applicability),
+ replace_left_sugg(cx, binop, &sugg, &mut applicability),
applicability,
);
return;
emit_suggestion(
cx,
binop.span,
- replace_right_sugg(cx, &binop, &sugg, &mut applicability),
+ replace_right_sugg(cx, binop, &sugg, &mut applicability),
applicability,
);
return;
"did you mean",
sugg,
applicability,
- )
+ );
}
fn ident_swap_sugg(
location: IdentLocation,
applicability: &mut Applicability,
) -> Option<String> {
- let left_ident = get_ident(&binop.left, location)?;
- let right_ident = get_ident(&binop.right, location)?;
+ let left_ident = get_ident(binop.left, location)?;
+ let right_ident = get_ident(binop.right, location)?;
let sugg = match (
paired_identifiers.contains(&left_ident),
// used instead, in these cases.
*applicability = Applicability::MaybeIncorrect;
- // We arbitraily choose one side to suggest changing,
+ // We arbitrarily choose one side to suggest changing,
// since we don't have a better guess. If the user
// ends up duplicating a clause, the `logic_bug` lint
// should catch it.
- let right_suggestion =
- suggestion_with_swapped_ident(cx, &binop.right, location, left_ident, applicability)?;
+ let right_suggestion = suggestion_with_swapped_ident(cx, binop.right, location, left_ident, applicability)?;
replace_right_sugg(cx, binop, &right_suggestion, applicability)
},
// We haven't seen a pair involving the left one, so
// it's probably what is wanted.
- let right_suggestion =
- suggestion_with_swapped_ident(cx, &binop.right, location, left_ident, applicability)?;
+ let right_suggestion = suggestion_with_swapped_ident(cx, binop.right, location, left_ident, applicability)?;
replace_right_sugg(cx, binop, &right_suggestion, applicability)
},
(true, false) => {
// We haven't seen a pair involving the right one, so
// it's probably what is wanted.
- let left_suggestion = suggestion_with_swapped_ident(cx, &binop.left, location, right_ident, applicability)?;
+ let left_suggestion = suggestion_with_swapped_ident(cx, binop.left, location, right_ident, applicability)?;
replace_left_sugg(cx, binop, &left_suggestion, applicability)
},
right: &'exprs Expr,
}
-impl BinaryOp<'exprs> {
+impl<'exprs> BinaryOp<'exprs> {
fn new(op: BinOpKind, span: Span, (left, right): (&'exprs Expr, &'exprs Expr)) -> Self {
Self { op, span, left, right }
}
}
fn extract_related_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
- append_opt_vecs(chained_binops(kind), if_statment_binops(kind))
+ append_opt_vecs(chained_binops(kind), if_statement_binops(kind))
}
-fn if_statment_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
+fn if_statement_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
match kind {
ExprKind::If(ref condition, _, _) => chained_binops(&condition.kind),
- ExprKind::Paren(ref e) => if_statment_binops(&e.kind),
+ ExprKind::Paren(ref e) => if_statement_binops(&e.kind),
ExprKind::Block(ref block, _) => {
let mut output = None;
for stmt in &block.stmts {
match stmt.kind {
StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => {
- output = append_opt_vecs(output, if_statment_binops(&e.kind));
+ output = append_opt_vecs(output, if_statement_binops(&e.kind));
},
_ => {},
}
fn append_opt_vecs<A>(target_opt: Option<Vec<A>>, source_opt: Option<Vec<A>>) -> Option<Vec<A>> {
match (target_opt, source_opt) {
- (Some(mut target), Some(mut source)) => {
+ (Some(mut target), Some(source)) => {
target.reserve(source.len());
- for op in source.drain(..) {
+ for op in source {
target.push(op);
}
Some(target)
}
}
-fn chained_binops_helper(left_outer: &'expr Expr, right_outer: &'expr Expr) -> Option<Vec<BinaryOp<'expr>>> {
+fn chained_binops_helper<'expr>(left_outer: &'expr Expr, right_outer: &'expr Expr) -> Option<Vec<BinaryOp<'expr>>> {
match (&left_outer.kind, &right_outer.kind) {
(
ExprKind::Paren(ref left_e) | ExprKind::Unary(_, ref left_e),
chained_binops_helper(left_left, left_right),
chained_binops_helper(right_left, right_right),
) {
- (Some(mut left_ops), Some(mut right_ops)) => {
+ (Some(mut left_ops), Some(right_ops)) => {
left_ops.reserve(right_ops.len());
- for op in right_ops.drain(..) {
+ for op in right_ops {
left_ops.push(op);
}
Some(left_ops)
impl AddAssign for IdentLocation {
fn add_assign(&mut self, other: Self) {
- *self = *self + other
+ *self = *self + other;
}
}
impl AddAssign for IdentDifference {
fn add_assign(&mut self, other: Self) {
- *self = *self + other
+ *self = *self + other;
}
}
// IdentIter, then the output of this function will be almost always be correct
// in practice.
//
- // If it turns out that problematic cases are more prelavent than we assume,
+ // If it turns out that problematic cases are more prevalent than we assume,
// then we should be able to change this function to do the correct traversal,
// without needing to change the rest of the code.
| (Repeat(_, _), Repeat(_, _))
| (Struct(_), Struct(_))
| (MacCall(_), MacCall(_))
- | (LlvmInlineAsm(_), LlvmInlineAsm(_))
| (InlineAsm(_), InlineAsm(_))
| (Ret(_), Ret(_))
| (Continue(_), Continue(_))
| (Await(_), Await(_))
| (Async(_, _, _), Async(_, _, _))
| (Block(_, _), Block(_, _))
- | (Closure(_, _, _, _, _, _), Closure(_, _, _, _, _, _))
+ | (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
| (Match(_, _), Match(_, _))
| (Loop(_, _), Loop(_, _))
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
| (While(_, _, _), While(_, _, _))
| (If(_, _, _), If(_, _, _))
- | (Let(_, _), Let(_, _))
+ | (Let(_, _, _), Let(_, _, _))
| (Type(_, _), Type(_, _))
| (Cast(_, _), Cast(_, _))
| (Lit(_), Lit(_))
| (Unary(_, _), Unary(_, _))
| (Binary(_, _, _), Binary(_, _, _))
| (Tup(_), Tup(_))
- | (MethodCall(_, _, _), MethodCall(_, _, _))
+ | (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
| (Call(_, _), Call(_, _))
| (ConstBlock(_), ConstBlock(_))
| (Array(_), Array(_))
Some(format!(
"{}{}{}",
snippet_with_applicability(cx, expr.span.with_hi(current_ident.span.lo()), "..", applicability),
- new_ident.to_string(),
+ new_ident,
snippet_with_applicability(cx, expr.span.with_lo(current_ident.span.hi()), "..", applicability),
))
})