mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-27 23:20:39 +00:00
Merge pull request #1613 from Manishearth/dont_ref_operator_args
Dont ref operator args
This commit is contained in:
commit
9c3c938761
25 changed files with 136 additions and 68 deletions
|
@ -77,10 +77,10 @@ fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_known_consts(cx: &LateContext, e: &Expr, s: &symbol::Symbol, module: &str) {
|
fn check_known_consts(cx: &LateContext, e: &Expr, s: &symbol::Symbol, module: &str) {
|
||||||
let s = &*s.as_str();
|
let s = s.as_str();
|
||||||
if s.parse::<f64>().is_ok() {
|
if s.parse::<f64>().is_ok() {
|
||||||
for &(constant, name, min_digits) in KNOWN_CONSTS {
|
for &(constant, name, min_digits) in KNOWN_CONSTS {
|
||||||
if is_approx_const(constant, s, min_digits) {
|
if is_approx_const(constant, &s, min_digits) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
APPROX_CONSTANT,
|
APPROX_CONSTANT,
|
||||||
e.span,
|
e.span,
|
||||||
|
|
|
@ -237,7 +237,7 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {
|
||||||
|
|
||||||
fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
|
||||||
if let LitKind::Str(ref is, _) = lit.node {
|
if let LitKind::Str(ref is, _) = lit.node {
|
||||||
if Version::parse(&*is.as_str()).is_ok() {
|
if Version::parse(&is.as_str()).is_ok() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl LintPass for BlackListedName {
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlackListedName {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlackListedName {
|
||||||
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
|
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
|
||||||
if let PatKind::Binding(_, _, ref ident, _) = pat.node {
|
if let PatKind::Binding(_, _, ref ident, _) = pat.node {
|
||||||
if self.blacklist.iter().any(|s| s == &*ident.node.as_str()) {
|
if self.blacklist.iter().any(|s| ident.node == *s) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
BLACKLISTED_NAME,
|
BLACKLISTED_NAME,
|
||||||
pat.span,
|
pat.span,
|
||||||
|
|
|
@ -90,7 +90,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
if attr.is_sugared_doc {
|
if attr.is_sugared_doc {
|
||||||
if let Some(ref doc) = attr.value_str() {
|
if let Some(ref doc) = attr.value_str() {
|
||||||
let doc = (*doc.as_str()).to_owned();
|
let doc = doc.to_string();
|
||||||
docs.extend_from_slice(&strip_doc_comment_decoration((doc, attr.span)));
|
docs.extend_from_slice(&strip_doc_comment_decoration((doc, attr.span)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ fn check_cond<'a, 'tcx, 'b>(
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(ref name, _, ref params) = check.node,
|
let ExprMethodCall(ref name, _, ref params) = check.node,
|
||||||
params.len() >= 2,
|
params.len() >= 2,
|
||||||
&*name.node.as_str() == "contains_key",
|
name.node == "contains_key",
|
||||||
let ExprAddrOf(_, ref key) = params[1].node
|
let ExprAddrOf(_, ref key) = params[1].node
|
||||||
], {
|
], {
|
||||||
let map = ¶ms[0];
|
let map = ¶ms[0];
|
||||||
|
@ -119,7 +119,7 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(ref name, _, ref params) = expr.node,
|
let ExprMethodCall(ref name, _, ref params) = expr.node,
|
||||||
params.len() == 3,
|
params.len() == 3,
|
||||||
&*name.node.as_str() == "insert",
|
name.node == "insert",
|
||||||
get_item_name(self.cx, self.map) == get_item_name(self.cx, ¶ms[0]),
|
get_item_name(self.cx, self.map) == get_item_name(self.cx, ¶ms[0]),
|
||||||
SpanlessEq::new(self.cx).eq_expr(self.key, ¶ms[1])
|
SpanlessEq::new(self.cx).eq_expr(self.key, ¶ms[1])
|
||||||
], {
|
], {
|
||||||
|
|
|
@ -232,7 +232,7 @@ impl EarlyLintPass for EnumVariantNames {
|
||||||
if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
|
if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
|
||||||
// constants don't have surrounding modules
|
// constants don't have surrounding modules
|
||||||
if !mod_camel.is_empty() {
|
if !mod_camel.is_empty() {
|
||||||
if mod_name == &item_name {
|
if *mod_name == item_name {
|
||||||
if let ItemKind::Mod(..) = item.node {
|
if let ItemKind::Mod(..) = item.node {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
MODULE_INCEPTION,
|
MODULE_INCEPTION,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use utils::{SpanlessEq, span_lint};
|
use utils::{SpanlessEq, span_lint, span_lint_and_then, multispan_sugg, snippet};
|
||||||
|
use utils::sugg::Sugg;
|
||||||
|
|
||||||
/// **What it does:** Checks for equal operands to comparison, logical and
|
/// **What it does:** Checks for equal operands to comparison, logical and
|
||||||
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
|
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
|
||||||
|
@ -23,23 +24,91 @@ declare_lint! {
|
||||||
"equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
|
"equal operands on both sides of a comparison or bitwise combination (e.g. `x == x`)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **What it does:** Checks for arguments to `==` which have their address taken to satisfy a bound
|
||||||
|
/// and suggests to dereference the other argument instead
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** It is more idiomatic to dereference the other argument.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// &x == y
|
||||||
|
/// ```
|
||||||
|
declare_lint! {
|
||||||
|
pub OP_REF,
|
||||||
|
Warn,
|
||||||
|
"taking a reference to satisfy the type constraints on `==`"
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy,Clone)]
|
#[derive(Copy,Clone)]
|
||||||
pub struct EqOp;
|
pub struct EqOp;
|
||||||
|
|
||||||
impl LintPass for EqOp {
|
impl LintPass for EqOp {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array!(EQ_OP)
|
lint_array!(EQ_OP, OP_REF)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprBinary(ref op, ref left, ref right) = e.node {
|
if let ExprBinary(ref op, ref left, ref right) = e.node {
|
||||||
if is_valid_operator(op) && SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
|
if is_valid_operator(op) {
|
||||||
span_lint(cx,
|
if SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
|
||||||
EQ_OP,
|
span_lint(cx,
|
||||||
e.span,
|
EQ_OP,
|
||||||
&format!("equal expressions as operands to `{}`", op.node.as_str()));
|
e.span,
|
||||||
|
&format!("equal expressions as operands to `{}`", op.node.as_str()));
|
||||||
|
} else {
|
||||||
|
match (&left.node, &right.node) {
|
||||||
|
(&ExprAddrOf(_, ref l), &ExprAddrOf(_, ref r)) => {
|
||||||
|
span_lint_and_then(cx,
|
||||||
|
OP_REF,
|
||||||
|
e.span,
|
||||||
|
"taken reference of both operands, which is done automatically by the operator anyway",
|
||||||
|
|db| {
|
||||||
|
let lsnip = snippet(cx, l.span, "...").to_string();
|
||||||
|
let rsnip = snippet(cx, r.span, "...").to_string();
|
||||||
|
multispan_sugg(db,
|
||||||
|
"use the values directly".to_string(),
|
||||||
|
vec![(left.span, lsnip),
|
||||||
|
(right.span, rsnip)]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(&ExprAddrOf(_, ref l), _) => {
|
||||||
|
span_lint_and_then(cx,
|
||||||
|
OP_REF,
|
||||||
|
e.span,
|
||||||
|
"taken reference of left operand",
|
||||||
|
|db| {
|
||||||
|
let lsnip = snippet(cx, l.span, "...").to_string();
|
||||||
|
let rsnip = Sugg::hir(cx, right, "...").deref().to_string();
|
||||||
|
multispan_sugg(db,
|
||||||
|
"dereference the right operand instead".to_string(),
|
||||||
|
vec![(left.span, lsnip),
|
||||||
|
(right.span, rsnip)]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(_, &ExprAddrOf(_, ref r)) => {
|
||||||
|
span_lint_and_then(cx,
|
||||||
|
OP_REF,
|
||||||
|
e.span,
|
||||||
|
"taken reference of right operand",
|
||||||
|
|db| {
|
||||||
|
let lsnip = Sugg::hir(cx, left, "...").deref().to_string();
|
||||||
|
let rsnip = snippet(cx, r.span, "...").to_string();
|
||||||
|
multispan_sugg(db,
|
||||||
|
"dereference the left operand instead".to_string(),
|
||||||
|
vec![(left.span, lsnip),
|
||||||
|
(right.span, rsnip)]);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Exp
|
||||||
let StmtDecl(ref decl, _) = block.stmts[0].node,
|
let StmtDecl(ref decl, _) = block.stmts[0].node,
|
||||||
let DeclItem(ref decl) = decl.node,
|
let DeclItem(ref decl) = decl.node,
|
||||||
let Some(NodeItem(decl)) = cx.tcx.hir.find(decl.id),
|
let Some(NodeItem(decl)) = cx.tcx.hir.find(decl.id),
|
||||||
&*decl.name.as_str() == "__STATIC_FMTSTR",
|
decl.name == "__STATIC_FMTSTR",
|
||||||
let ItemStatic(_, _, ref expr) = decl.node,
|
let ItemStatic(_, _, ref expr) = decl.node,
|
||||||
let ExprAddrOf(_, ref expr) = cx.tcx.hir.body(*expr).value.node, // &["…", "…", …]
|
let ExprAddrOf(_, ref expr) = cx.tcx.hir.body(*expr).value.node, // &["…", "…", …]
|
||||||
let ExprArray(ref exprs) = expr.node,
|
let ExprArray(ref exprs) = expr.node,
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {
|
||||||
|
|
||||||
fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]) {
|
fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]) {
|
||||||
fn is_named_self(cx: &LateContext, item: &TraitItemRef, name: &str) -> bool {
|
fn is_named_self(cx: &LateContext, item: &TraitItemRef, name: &str) -> bool {
|
||||||
&*item.name.as_str() == name &&
|
item.name == name &&
|
||||||
if let AssociatedItemKind::Method { has_self } = item.kind {
|
if let AssociatedItemKind::Method { has_self } = item.kind {
|
||||||
has_self &&
|
has_self &&
|
||||||
{
|
{
|
||||||
|
@ -116,7 +116,7 @@ fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]
|
||||||
|
|
||||||
fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
||||||
fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
|
fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
|
||||||
&*item.name.as_str() == name &&
|
item.name == name &&
|
||||||
if let AssociatedItemKind::Method { has_self } = item.kind {
|
if let AssociatedItemKind::Method { has_self } = item.kind {
|
||||||
has_self &&
|
has_self &&
|
||||||
{
|
{
|
||||||
|
@ -155,22 +155,22 @@ fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[ImplItemRef]) {
|
||||||
fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str) {
|
fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str) {
|
||||||
// check if we are in an is_empty() method
|
// check if we are in an is_empty() method
|
||||||
if let Some(name) = get_item_name(cx, left) {
|
if let Some(name) = get_item_name(cx, left) {
|
||||||
if &*name.as_str() == "is_empty" {
|
if name == "is_empty" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match (&left.node, &right.node) {
|
match (&left.node, &right.node) {
|
||||||
(&ExprLit(ref lit), &ExprMethodCall(ref method, _, ref args)) |
|
(&ExprLit(ref lit), &ExprMethodCall(ref method, _, ref args)) |
|
||||||
(&ExprMethodCall(ref method, _, ref args), &ExprLit(ref lit)) => {
|
(&ExprMethodCall(ref method, _, ref args), &ExprLit(ref lit)) => {
|
||||||
check_len_zero(cx, span, &method.node, args, lit, op)
|
check_len_zero(cx, span, method.node, args, lit, op)
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_len_zero(cx: &LateContext, span: Span, name: &Name, args: &[Expr], lit: &Lit, op: &str) {
|
fn check_len_zero(cx: &LateContext, span: Span, name: Name, args: &[Expr], lit: &Lit, op: &str) {
|
||||||
if let Spanned { node: LitKind::Int(0, _), .. } = *lit {
|
if let Spanned { node: LitKind::Int(0, _), .. } = *lit {
|
||||||
if &*name.as_str() == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
if name == "len" && args.len() == 1 && has_is_empty(cx, &args[0]) {
|
||||||
span_lint_and_then(cx, LEN_ZERO, span, "length comparison to zero", |db| {
|
span_lint_and_then(cx, LEN_ZERO, span, "length comparison to zero", |db| {
|
||||||
db.span_suggestion(span,
|
db.span_suggestion(span,
|
||||||
"consider using `is_empty`",
|
"consider using `is_empty`",
|
||||||
|
@ -185,7 +185,7 @@ fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
|
||||||
/// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
/// Get an `AssociatedItem` and return true if it matches `is_empty(self)`.
|
||||||
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
|
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
|
||||||
if let ty::AssociatedKind::Method = item.kind {
|
if let ty::AssociatedKind::Method = item.kind {
|
||||||
if &*item.name.as_str() == "is_empty" {
|
if item.name == "is_empty" {
|
||||||
let sig = cx.tcx.item_type(item.def_id).fn_sig();
|
let sig = cx.tcx.item_type(item.def_id).fn_sig();
|
||||||
let ty = sig.skip_binder();
|
let ty = sig.skip_binder();
|
||||||
ty.inputs().len() == 1
|
ty.inputs().len() == 1
|
||||||
|
|
|
@ -199,7 +199,7 @@ fn allowed_lts_from(named_lts: &[LifetimeDef]) -> HashSet<RefLt> {
|
||||||
|
|
||||||
fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
|
||||||
for lt in bounds_lts {
|
for lt in bounds_lts {
|
||||||
if &*lt.name.as_str() != "'static" {
|
if lt.name != "'static" {
|
||||||
vec.push(RefLt::Named(lt.name));
|
vec.push(RefLt::Named(lt.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
||||||
|
|
||||||
fn record(&mut self, lifetime: &Option<Lifetime>) {
|
fn record(&mut self, lifetime: &Option<Lifetime>) {
|
||||||
if let Some(ref lt) = *lifetime {
|
if let Some(ref lt) = *lifetime {
|
||||||
if &*lt.name.as_str() == "'static" {
|
if lt.name == "'static" {
|
||||||
self.lts.push(RefLt::Static);
|
self.lts.push(RefLt::Static);
|
||||||
} else if lt.is_elided() {
|
} else if lt.is_elided() {
|
||||||
self.lts.push(RefLt::Unnamed);
|
self.lts.push(RefLt::Unnamed);
|
||||||
|
|
|
@ -389,8 +389,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
|
||||||
let iter_expr = &method_args[0];
|
let iter_expr = &method_args[0];
|
||||||
let lhs_constructor = last_path_segment(qpath);
|
let lhs_constructor = last_path_segment(qpath);
|
||||||
if &*method_name.node.as_str() == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
if method_name.node == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
|
||||||
&*lhs_constructor.name.as_str() == "Some" && !is_refutable(cx, &pat_args[0]) &&
|
lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) &&
|
||||||
!is_iterator_used_after_while_let(cx, iter_expr) {
|
!is_iterator_used_after_while_let(cx, iter_expr) {
|
||||||
let iterator = snippet(cx, method_args[0].span, "_");
|
let iterator = snippet(cx, method_args[0].span, "_");
|
||||||
let loop_var = snippet(cx, pat_args[0].span, "_");
|
let loop_var = snippet(cx, pat_args[0].span, "_");
|
||||||
|
@ -409,7 +409,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
|
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
|
||||||
if let StmtSemi(ref expr, _) = stmt.node {
|
if let StmtSemi(ref expr, _) = stmt.node {
|
||||||
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
||||||
if args.len() == 1 && &*method.node.as_str() == "collect" &&
|
if args.len() == 1 && method.node == "collect" &&
|
||||||
match_trait_method(cx, expr, &paths::ITERATOR) {
|
match_trait_method(cx, expr, &paths::ITERATOR) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
UNUSED_COLLECT,
|
UNUSED_COLLECT,
|
||||||
|
@ -579,10 +579,10 @@ fn is_len_call(expr: &Expr, var: &Name) -> bool {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprMethodCall(method, _, ref len_args) = expr.node,
|
let ExprMethodCall(method, _, ref len_args) = expr.node,
|
||||||
len_args.len() == 1,
|
len_args.len() == 1,
|
||||||
&*method.node.as_str() == "len",
|
method.node == "len",
|
||||||
let ExprPath(QPath::Resolved(_, ref path)) = len_args[0].node,
|
let ExprPath(QPath::Resolved(_, ref path)) = len_args[0].node,
|
||||||
path.segments.len() == 1,
|
path.segments.len() == 1,
|
||||||
&path.segments[0].name == var
|
path.segments[0].name == *var
|
||||||
], {
|
], {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
|
@ -664,11 +664,11 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
||||||
if let ExprMethodCall(ref method, _, ref args) = arg.node {
|
if let ExprMethodCall(ref method, _, ref args) = arg.node {
|
||||||
// just the receiver, no arguments
|
// just the receiver, no arguments
|
||||||
if args.len() == 1 {
|
if args.len() == 1 {
|
||||||
let method_name = &*method.node.as_str();
|
let method_name = method.node.as_str();
|
||||||
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
|
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
|
||||||
if method_name == "iter" || method_name == "iter_mut" {
|
if method_name == "iter" || method_name == "iter_mut" {
|
||||||
if is_ref_iterable_type(cx, &args[0]) {
|
if is_ref_iterable_type(cx, &args[0]) {
|
||||||
lint_iter_method(cx, args, arg, method_name);
|
lint_iter_method(cx, args, arg, &method_name);
|
||||||
}
|
}
|
||||||
} else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
} else if method_name == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
||||||
let method_call = ty::MethodCall::expr(arg.id);
|
let method_call = ty::MethodCall::expr(arg.id);
|
||||||
|
@ -680,7 +680,7 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
||||||
let fn_arg_tys = fn_ty.fn_args();
|
let fn_arg_tys = fn_ty.fn_args();
|
||||||
assert_eq!(fn_arg_tys.skip_binder().len(), 1);
|
assert_eq!(fn_arg_tys.skip_binder().len(), 1);
|
||||||
if fn_arg_tys.skip_binder()[0].is_region_ptr() {
|
if fn_arg_tys.skip_binder()[0].is_region_ptr() {
|
||||||
lint_iter_method(cx, args, arg, method_name);
|
lint_iter_method(cx, args, arg, &method_name);
|
||||||
} else {
|
} else {
|
||||||
let object = snippet(cx, args[0].span, "_");
|
let object = snippet(cx, args[0].span, "_");
|
||||||
span_lint_and_sugg(cx,
|
span_lint_and_sugg(cx,
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
// call to .map()
|
// call to .map()
|
||||||
if let ExprMethodCall(name, _, ref args) = expr.node {
|
if let ExprMethodCall(name, _, ref args) = expr.node {
|
||||||
if &*name.node.as_str() == "map" && args.len() == 2 {
|
if name.node == "map" && args.len() == 2 {
|
||||||
match args[1].node {
|
match args[1].node {
|
||||||
ExprClosure(_, ref decl, closure_eid, _) => {
|
ExprClosure(_, ref decl, closure_eid, _) => {
|
||||||
let body = cx.tcx.hir.body(closure_eid);
|
let body = cx.tcx.hir.body(closure_eid);
|
||||||
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
}
|
}
|
||||||
// explicit clone() calls ( .map(|x| x.clone()) )
|
// explicit clone() calls ( .map(|x| x.clone()) )
|
||||||
else if let ExprMethodCall(clone_call, _, ref clone_args) = closure_expr.node {
|
else if let ExprMethodCall(clone_call, _, ref clone_args) = closure_expr.node {
|
||||||
if &*clone_call.node.as_str() == "clone" &&
|
if clone_call.node == "clone" &&
|
||||||
clone_args.len() == 1 &&
|
clone_args.len() == 1 &&
|
||||||
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
|
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
|
||||||
expr_eq_name(&clone_args[0], arg_ident)
|
expr_eq_name(&clone_args[0], arg_ident)
|
||||||
|
|
|
@ -257,7 +257,7 @@ fn check_single_match_opt_like(
|
||||||
};
|
};
|
||||||
|
|
||||||
for &(ty_path, pat_path) in candidates {
|
for &(ty_path, pat_path) in candidates {
|
||||||
if &path == pat_path && match_type(cx, ty, ty_path) {
|
if path == *pat_path && match_type(cx, ty, ty_path) {
|
||||||
report_single_match_single_pattern(cx, ex, arms, expr, els);
|
report_single_match_single_pattern(cx, ex, arms, expr, els);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -607,14 +607,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
lint_or_fun_call(cx, expr, &name.node.as_str(), args);
|
lint_or_fun_call(cx, expr, &name.node.as_str(), args);
|
||||||
|
|
||||||
let self_ty = cx.tables.expr_ty_adjusted(&args[0]);
|
let self_ty = cx.tables.expr_ty_adjusted(&args[0]);
|
||||||
if args.len() == 1 && &*name.node.as_str() == "clone" {
|
if args.len() == 1 && name.node == "clone" {
|
||||||
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
lint_clone_on_copy(cx, expr, &args[0], self_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self_ty.sty {
|
match self_ty.sty {
|
||||||
ty::TyRef(_, ty) if ty.ty.sty == ty::TyStr => {
|
ty::TyRef(_, ty) if ty.ty.sty == ty::TyStr => {
|
||||||
for &(method, pos) in &PATTERN_METHODS {
|
for &(method, pos) in &PATTERN_METHODS {
|
||||||
if &*name.node.as_str() == method && args.len() > pos {
|
if name.node == method && args.len() > pos {
|
||||||
lint_single_char_pattern(cx, expr, &args[pos]);
|
lint_single_char_pattern(cx, expr, &args[pos]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,7 +646,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
], {
|
], {
|
||||||
// check missing trait implementations
|
// check missing trait implementations
|
||||||
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
|
for &(method_name, n_args, self_kind, out_type, trait_name) in &TRAIT_METHODS {
|
||||||
if &*name.as_str() == method_name &&
|
if name == method_name &&
|
||||||
sig.decl.inputs.len() == n_args &&
|
sig.decl.inputs.len() == n_args &&
|
||||||
out_type.matches(&sig.decl.output) &&
|
out_type.matches(&sig.decl.output) &&
|
||||||
self_kind.matches(&first_arg_ty, &first_arg, &self_ty, false) {
|
self_kind.matches(&first_arg_ty, &first_arg, &self_ty, false) {
|
||||||
|
@ -683,7 +683,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_ty = return_ty(cx, implitem.id);
|
let ret_ty = return_ty(cx, implitem.id);
|
||||||
if &*name.as_str() == "new" &&
|
if name == "new" &&
|
||||||
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id)) {
|
!ret_ty.walk().any(|t| same_tys(cx, t, ty, implitem.id)) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
NEW_RET_NO_SELF,
|
NEW_RET_NO_SELF,
|
||||||
|
@ -712,7 +712,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
|
||||||
|
|
||||||
if name == "unwrap_or" {
|
if name == "unwrap_or" {
|
||||||
if let hir::ExprPath(ref qpath) = fun.node {
|
if let hir::ExprPath(ref qpath) = fun.node {
|
||||||
let path: &str = &*last_path_segment(qpath).name.as_str();
|
let path = &*last_path_segment(qpath).name.as_str();
|
||||||
|
|
||||||
if ["default", "new"].contains(&path) {
|
if ["default", "new"].contains(&path) {
|
||||||
let arg_ty = cx.tables.expr_ty(arg);
|
let arg_ty = cx.tables.expr_ty(arg);
|
||||||
|
@ -991,7 +991,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
|
||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ExprMethodCall(name, _, ref args) = expr.node {
|
if let hir::ExprMethodCall(name, _, ref args) = expr.node {
|
||||||
if &*name.node.as_str() == "iter" && may_slice(cx, cx.tables.expr_ty(&args[0])) {
|
if name.node == "iter" && may_slice(cx, cx.tables.expr_ty(&args[0])) {
|
||||||
sugg::Sugg::hir_opt(cx, &args[0]).map(|sugg| sugg.addr())
|
sugg::Sugg::hir_opt(cx, &args[0]).map(|sugg| sugg.addr())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1209,7 +1209,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
|
||||||
arg_char.len() == 1,
|
arg_char.len() == 1,
|
||||||
let hir::ExprPath(ref qpath) = fun.node,
|
let hir::ExprPath(ref qpath) = fun.node,
|
||||||
let Some(segment) = single_segment_path(qpath),
|
let Some(segment) = single_segment_path(qpath),
|
||||||
&*segment.name.as_str() == "Some"
|
segment.name == "Some"
|
||||||
], {
|
], {
|
||||||
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
|
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(name) = get_item_name(cx, expr) {
|
if let Some(name) = get_item_name(cx, expr) {
|
||||||
let name = &*name.as_str();
|
let name = name.as_str();
|
||||||
if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") ||
|
if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") ||
|
||||||
name.ends_with("_eq") {
|
name.ends_with("_eq") {
|
||||||
return;
|
return;
|
||||||
|
@ -335,7 +335,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
let binding = last_path_segment(qpath).name.as_str();
|
let binding = last_path_segment(qpath).name.as_str();
|
||||||
if binding.starts_with('_') &&
|
if binding.starts_with('_') &&
|
||||||
!binding.starts_with("__") &&
|
!binding.starts_with("__") &&
|
||||||
&*binding != "_result" && // FIXME: #944
|
binding != "_result" && // FIXME: #944
|
||||||
is_used(cx, expr) &&
|
is_used(cx, expr) &&
|
||||||
// don't lint if the declaration is in a macro
|
// don't lint if the declaration is in a macro
|
||||||
non_macro_local(cx, &cx.tables.qpath_def(qpath, expr.id)) {
|
non_macro_local(cx, &cx.tables.qpath_def(qpath, expr.id)) {
|
||||||
|
@ -378,7 +378,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
|
|
||||||
fn check_nan(cx: &LateContext, path: &Path, expr: &Expr) {
|
fn check_nan(cx: &LateContext, path: &Path, expr: &Expr) {
|
||||||
if !in_constant(cx, expr.id) {
|
if !in_constant(cx, expr.id) {
|
||||||
path.segments.last().map(|seg| if &*seg.name.as_str() == "NAN" {
|
path.segments.last().map(|seg| if seg.name == "NAN" {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
CMP_NAN,
|
CMP_NAN,
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -425,7 +425,7 @@ fn is_float(cx: &LateContext, expr: &Expr) -> bool {
|
||||||
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
|
fn check_to_owned(cx: &LateContext, expr: &Expr, other: &Expr, left: bool, op: Span) {
|
||||||
let (arg_ty, snip) = match expr.node {
|
let (arg_ty, snip) = match expr.node {
|
||||||
ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
|
ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) if args.len() == 1 => {
|
||||||
let name = &*name.as_str();
|
let name = name.as_str();
|
||||||
if name == "to_string" || name == "to_owned" && is_str_arg(cx, args) {
|
if name == "to_string" || name == "to_owned" && is_str_arg(cx, args) {
|
||||||
(cx.tables.expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
|
(cx.tables.expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
a.meta_item_list().is_some(),
|
a.meta_item_list().is_some(),
|
||||||
let Some(name) = a.name(),
|
let Some(name) = a.name(),
|
||||||
&*name.as_str() == "proc_macro_derive",
|
name == "proc_macro_derive",
|
||||||
], {
|
], {
|
||||||
return;
|
return;
|
||||||
}}
|
}}
|
||||||
|
@ -102,7 +102,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||||
let fn_sig = cx.tcx.item_type(fn_def_id).fn_sig();
|
let fn_sig = cx.tcx.item_type(fn_def_id).fn_sig();
|
||||||
let fn_sig = cx.tcx.liberate_late_bound_regions(param_env.free_id_outlive, &fn_sig);
|
let fn_sig = cx.tcx.liberate_late_bound_regions(param_env.free_id_outlive, &fn_sig);
|
||||||
|
|
||||||
for ((input, ty), arg) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments) {
|
for ((input, &ty), arg) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments) {
|
||||||
|
|
||||||
// Determines whether `ty` implements `Borrow<U>` (U != ty) specifically.
|
// Determines whether `ty` implements `Borrow<U>` (U != ty) specifically.
|
||||||
// This is needed due to the `Borrow<T> for T` blanket impl.
|
// This is needed due to the `Borrow<T> for T` blanket impl.
|
||||||
|
@ -112,8 +112,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
.filter(|tpred| tpred.def_id() == borrow_trait && &tpred.self_ty() == ty)
|
.filter(|tpred| tpred.def_id() == borrow_trait && tpred.self_ty() == ty)
|
||||||
.any(|tpred| &tpred.input_types().nth(1).expect("Borrow trait must have an parameter") != ty);
|
.any(|tpred| tpred.input_types().nth(1).expect("Borrow trait must have an parameter") != ty);
|
||||||
|
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
!is_self(arg),
|
!is_self(arg),
|
||||||
|
@ -141,7 +141,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
||||||
match_type(cx, ty, &paths::VEC),
|
match_type(cx, ty, &paths::VEC),
|
||||||
let TyPath(QPath::Resolved(_, ref path)) = input.node,
|
let TyPath(QPath::Resolved(_, ref path)) = input.node,
|
||||||
let Some(elem_ty) = path.segments.iter()
|
let Some(elem_ty) = path.segments.iter()
|
||||||
.find(|seg| &*seg.name.as_str() == "Vec")
|
.find(|seg| seg.name == "Vec")
|
||||||
.map(|ps| ps.parameters.types()[0]),
|
.map(|ps| ps.parameters.types()[0]),
|
||||||
], {
|
], {
|
||||||
let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_"));
|
let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_"));
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
|
||||||
// can't be implemented by default
|
// can't be implemented by default
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if decl.inputs.is_empty() && &*name.as_str() == "new" && cx.access_levels.is_reachable(id) {
|
if decl.inputs.is_empty() && name == "new" && cx.access_levels.is_reachable(id) {
|
||||||
let self_ty = cx.tcx
|
let self_ty = cx.tcx
|
||||||
.item_type(cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id)));
|
.item_type(cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id)));
|
||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSensical {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
if let ExprMethodCall(ref name, _, ref arguments) = e.node {
|
||||||
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&arguments[0]));
|
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(&arguments[0]));
|
||||||
if &*name.node.as_str() == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
if name.node == "open" && match_type(cx, obj_ty, &paths::OPEN_OPTIONS) {
|
||||||
let mut options = Vec::new();
|
let mut options = Vec::new();
|
||||||
get_open_options(cx, &arguments[0], &mut options);
|
get_open_options(cx, &arguments[0], &mut options);
|
||||||
check_open_options(cx, &options, e.span);
|
check_open_options(cx, &options, e.span);
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node,
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = second.node,
|
||||||
&path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
|
path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0],
|
||||||
cx.tables.expr_ty(ident1).is_integral(),
|
cx.tables.expr_ty(ident1).is_integral(),
|
||||||
cx.tables.expr_ty(ident2).is_integral()
|
cx.tables.expr_ty(ident2).is_integral()
|
||||||
], {
|
], {
|
||||||
|
@ -62,7 +62,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OverflowCheckConditional {
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path1)) = ident1.node,
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path2)) = ident2.node,
|
||||||
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node,
|
let Expr_::ExprPath(QPath::Resolved(_, ref path3)) = first.node,
|
||||||
&path1.segments[0] == &path3.segments[0] || &path2.segments[0] == &path3.segments[0],
|
path1.segments[0] == path3.segments[0] || path2.segments[0] == path3.segments[0],
|
||||||
cx.tables.expr_ty(ident1).is_integral(),
|
cx.tables.expr_ty(ident1).is_integral(),
|
||||||
cx.tables.expr_ty(ident2).is_integral()
|
cx.tables.expr_ty(ident2).is_integral()
|
||||||
], {
|
], {
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
trait_ref.path.def.def_id() == cx.tcx.lang_items.eq_trait().unwrap(),
|
trait_ref.path.def.def_id() == cx.tcx.lang_items.eq_trait().unwrap(),
|
||||||
], {
|
], {
|
||||||
for impl_item in impl_items {
|
for impl_item in impl_items {
|
||||||
if &*impl_item.name.as_str() == "ne" {
|
if impl_item.name == "ne" {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
PARTIALEQ_NE_IMPL,
|
PARTIALEQ_NE_IMPL,
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl LintPass for StepByZero {
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
if let ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) = expr.node {
|
if let ExprMethodCall(Spanned { node: ref name, .. }, _, ref args) = expr.node {
|
||||||
let name = &*name.as_str();
|
let name = name.as_str();
|
||||||
|
|
||||||
// Range with step_by(0).
|
// Range with step_by(0).
|
||||||
if name == "step_by" && args.len() == 2 && has_step_by(cx, &args[0]) && is_integer_literal(&args[1], 0) {
|
if name == "step_by" && args.len() == 2 && has_step_by(cx, &args[0]) && is_integer_literal(&args[1], 0) {
|
||||||
|
@ -63,14 +63,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
|
||||||
let zip_arg = &args[1];
|
let zip_arg = &args[1];
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
// .iter() call
|
// .iter() call
|
||||||
let ExprMethodCall( Spanned { node: ref iter_name, .. }, _, ref iter_args ) = *iter,
|
let ExprMethodCall( Spanned { node: iter_name, .. }, _, ref iter_args ) = *iter,
|
||||||
&*iter_name.as_str() == "iter",
|
iter_name == "iter",
|
||||||
// range expression in .zip() call: 0..x.len()
|
// range expression in .zip() call: 0..x.len()
|
||||||
let Some(higher::Range { start: Some(ref start), end: Some(ref end), .. }) = higher::range(zip_arg),
|
let Some(higher::Range { start: Some(ref start), end: Some(ref end), .. }) = higher::range(zip_arg),
|
||||||
is_integer_literal(start, 0),
|
is_integer_literal(start, 0),
|
||||||
// .len() call
|
// .len() call
|
||||||
let ExprMethodCall(Spanned { node: ref len_name, .. }, _, ref len_args) = end.node,
|
let ExprMethodCall(Spanned { node: len_name, .. }, _, ref len_args) = end.node,
|
||||||
&*len_name.as_str() == "len" && len_args.len() == 1,
|
len_name == "len" && len_args.len() == 1,
|
||||||
// .iter() and .len() called on same Path
|
// .iter() and .len() called on same Path
|
||||||
let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node,
|
let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node,
|
||||||
let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node,
|
let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node,
|
||||||
|
|
|
@ -203,7 +203,7 @@ fn check_regex(cx: &LateContext, expr: &Expr, utf8: bool) {
|
||||||
|
|
||||||
if let ExprLit(ref lit) = expr.node {
|
if let ExprLit(ref lit) = expr.node {
|
||||||
if let LitKind::Str(ref r, _) = lit.node {
|
if let LitKind::Str(ref r, _) = lit.node {
|
||||||
let r = &*r.as_str();
|
let r = &r.as_str();
|
||||||
match builder.parse(r) {
|
match builder.parse(r) {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
if let Some(repl) = is_trivial_regex(&r) {
|
if let Some(repl) = is_trivial_regex(&r) {
|
||||||
|
|
|
@ -143,7 +143,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
||||||
use utils::{snippet, in_macro};
|
use utils::{snippet, in_macro};
|
||||||
|
|
||||||
if let ExprMethodCall(ref name, _, ref args) = e.node {
|
if let ExprMethodCall(ref name, _, ref args) = e.node {
|
||||||
if &*name.node.as_str() == "as_bytes" {
|
if name.node == "as_bytes" {
|
||||||
if let ExprLit(ref lit) = args[0].node {
|
if let ExprLit(ref lit) = args[0].node {
|
||||||
if let LitKind::Str(ref lit_content, _) = lit.node {
|
if let LitKind::Str(ref lit_content, _) = lit.node {
|
||||||
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(cx, args[0].span) {
|
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(cx, args[0].span) {
|
||||||
|
|
|
@ -56,8 +56,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedIoAmount {
|
||||||
},
|
},
|
||||||
|
|
||||||
hir::ExprMethodCall(ref symbol, _, ref args) => {
|
hir::ExprMethodCall(ref symbol, _, ref args) => {
|
||||||
let symbol = &*symbol.node.as_str();
|
match &*symbol.node.as_str() {
|
||||||
match symbol {
|
|
||||||
"expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
|
"expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
|
||||||
check_method_call(cx, &args[0], expr);
|
check_method_call(cx, &args[0], expr);
|
||||||
},
|
},
|
||||||
|
|
|
@ -179,7 +179,7 @@ pub fn match_def_path(tcx: ty::TyCtxt, def_id: DefId, path: &[&str]) -> bool {
|
||||||
|
|
||||||
tcx.push_item_path(&mut apb, def_id);
|
tcx.push_item_path(&mut apb, def_id);
|
||||||
|
|
||||||
apb.names.len() == path.len() && apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b)
|
apb.names.len() == path.len() && apb.names.into_iter().zip(path.iter()).all(|(a, &b)| *a == *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if type is struct, enum or union type with given def path.
|
/// Check if type is struct, enum or union type with given def path.
|
||||||
|
@ -680,7 +680,7 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
|
||||||
}
|
}
|
||||||
if let Some(ref value) = attr.value_str() {
|
if let Some(ref value) = attr.value_str() {
|
||||||
if attr.name().map_or(false, |n| n == name) {
|
if attr.name().map_or(false, |n| n == name) {
|
||||||
if let Ok(value) = FromStr::from_str(&*value.as_str()) {
|
if let Ok(value) = FromStr::from_str(&value.as_str()) {
|
||||||
attr::mark_used(attr);
|
attr::mark_used(attr);
|
||||||
f(value)
|
f(value)
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue