use clippy_utils::ty::has_drop;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource};
+use rustc_hir::{is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::ops::Deref;
ExprKind::Call(callee, args) => {
if let ExprKind::Path(ref qpath) = callee.kind {
let res = cx.qpath_res(qpath, callee.hir_id);
- match res {
- Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..) => {
- !has_drop(cx, cx.typeck_results().expr_ty(expr))
- && args.iter().all(|arg| has_no_effect(cx, arg))
- },
- _ => false,
+ let def_matched = matches!(
+ res,
+ Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)
+ );
+ if def_matched || is_range_literal(expr) {
+ !has_drop(cx, cx.typeck_results().expr_ty(expr)) && args.iter().all(|arg| has_no_effect(cx, arg))
+ } else {
+ false
}
} else {
false
if has_no_effect(cx, expr) {
span_lint_hir(cx, NO_EFFECT, expr.hir_id, stmt.span, "statement with no effect");
} else if let Some(reduced) = reduce_expression(cx, expr) {
- let mut snippet = String::new();
- for e in reduced {
+ for e in &reduced {
if e.span.from_expansion() {
return;
}
- if let Some(snip) = snippet_opt(cx, e.span) {
- snippet.push_str(&snip);
- snippet.push(';');
- } else {
- return;
+ }
+ if let ExprKind::Index(..) = &expr.kind {
+ let snippet;
+ if_chain! {
+ if let Some(arr) = snippet_opt(cx, reduced[0].span);
+ if let Some(func) = snippet_opt(cx, reduced[1].span);
+ then {
+ snippet = format!("assert!({}.len() > {});", &arr, &func);
+ } else {
+ return;
+ }
+ }
+ span_lint_hir_and_then(
+ cx,
+ UNNECESSARY_OPERATION,
+ expr.hir_id,
+ stmt.span,
+ "unnecessary operation",
+ |diag| {
+ diag.span_suggestion(
+ stmt.span,
+ "statement can be written as",
+ snippet,
+ Applicability::MaybeIncorrect,
+ );
+ },
+ );
+ } else {
+ let mut snippet = String::new();
+ for e in reduced {
+ if let Some(snip) = snippet_opt(cx, e.span) {
+ snippet.push_str(&snip);
+ snippet.push(';');
+ } else {
+ return;
+ }
}
+ span_lint_hir_and_then(
+ cx,
+ UNNECESSARY_OPERATION,
+ expr.hir_id,
+ stmt.span,
+ "unnecessary operation",
+ |diag| {
+ diag.span_suggestion(
+ stmt.span,
+ "statement can be reduced to",
+ snippet,
+ Applicability::MachineApplicable,
+ );
+ },
+ );
}
- span_lint_hir_and_then(
- cx,
- UNNECESSARY_OPERATION,
- expr.hir_id,
- stmt.span,
- "statement can be reduced",
- |diag| {
- diag.span_suggestion(stmt.span, "replace it with", snippet, Applicability::MachineApplicable);
- },
- );
}
}
}