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"
}
"did you mean",
sugg,
applicability,
- )
+ );
}
fn ident_swap_sugg(
// 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.
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(_))
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),
))
})