Skip to content

Dont ref operator args #1613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clippy_lints/src/approx_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
let s = &*s.as_str();
let s = s.as_str();
if s.parse::<f64>().is_ok() {
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,
APPROX_CONSTANT,
e.span,
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ fn check_attrs(cx: &LateContext, span: Span, name: &Name, attrs: &[Attribute]) {

fn check_semver(cx: &LateContext, span: Span, lit: &Lit) {
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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/blacklisted_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl LintPass for BlackListedName {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlackListedName {
fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
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,
BLACKLISTED_NAME,
pat.span,
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext, valid_idents: &[String], attrs: &'a [a
for attr in attrs {
if attr.is_sugared_doc {
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)));
}
}
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn check_cond<'a, 'tcx, 'b>(
if_let_chain! {[
let ExprMethodCall(ref name, _, ref params) = check.node,
params.len() >= 2,
&*name.node.as_str() == "contains_key",
name.node == "contains_key",
let ExprAddrOf(_, ref key) = params[1].node
], {
let map = &params[0];
Expand Down Expand Up @@ -119,7 +119,7 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for InsertVisitor<'a, 'tcx, 'b> {
if_let_chain! {[
let ExprMethodCall(ref name, _, ref params) = expr.node,
params.len() == 3,
&*name.node.as_str() == "insert",
name.node == "insert",
get_item_name(self.cx, self.map) == get_item_name(self.cx, &params[0]),
SpanlessEq::new(self.cx).eq_expr(self.key, &params[1])
], {
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/enum_variants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl EarlyLintPass for EnumVariantNames {
if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
// constants don't have surrounding modules
if !mod_camel.is_empty() {
if mod_name == &item_name {
if *mod_name == item_name {
if let ItemKind::Mod(..) = item.node {
span_lint(cx,
MODULE_INCEPTION,
Expand Down
83 changes: 76 additions & 7 deletions clippy_lints/src/eq_op.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc::hir::*;
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
/// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,
Expand All @@ -23,23 +24,91 @@ declare_lint! {
"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)]
pub struct EqOp;

impl LintPass for EqOp {
fn get_lints(&self) -> LintArray {
lint_array!(EQ_OP)
lint_array!(EQ_OP, OP_REF)
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
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) {
span_lint(cx,
EQ_OP,
e.span,
&format!("equal expressions as operands to `{}`", op.node.as_str()));
if is_valid_operator(op) {
if SpanlessEq::new(cx).ignore_fn().eq_expr(left, right) {
span_lint(cx,
EQ_OP,
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)]);
}
)
}
_ => {}
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 DeclItem(ref decl) = decl.node,
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 ExprAddrOf(_, ref expr) = cx.tcx.hir.body(*expr).value.node, // &["…", "…", …]
let ExprArray(ref exprs) = expr.node,
Expand Down
14 changes: 7 additions & 7 deletions clippy_lints/src/len_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LenZero {

fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[TraitItemRef]) {
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 {
has_self &&
{
Expand All @@ -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 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 {
has_self &&
{
Expand Down Expand Up @@ -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) {
// check if we are in an is_empty() method
if let Some(name) = get_item_name(cx, left) {
if &*name.as_str() == "is_empty" {
if name == "is_empty" {
return;
}
}
match (&left.node, &right.node) {
(&ExprLit(ref lit), &ExprMethodCall(ref method, _, ref args)) |
(&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 &*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| {
db.span_suggestion(span,
"consider using `is_empty`",
Expand All @@ -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)`.
fn is_is_empty(cx: &LateContext, item: &ty::AssociatedItem) -> bool {
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 ty = sig.skip_binder();
ty.inputs().len() == 1
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
for lt in bounds_lts {
if &*lt.name.as_str() != "'static" {
if lt.name != "'static" {
vec.push(RefLt::Named(lt.name));
}
}
Expand Down Expand Up @@ -228,7 +228,7 @@ impl<'v, 't> RefVisitor<'v, 't> {

fn record(&mut self, lifetime: &Option<Lifetime>) {
if let Some(ref lt) = *lifetime {
if &*lt.name.as_str() == "'static" {
if lt.name == "'static" {
self.lts.push(RefLt::Static);
} else if lt.is_elided() {
self.lts.push(RefLt::Unnamed);
Expand Down
16 changes: 8 additions & 8 deletions clippy_lints/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
let iter_expr = &method_args[0];
let lhs_constructor = last_path_segment(qpath);
if &*method_name.node.as_str() == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
&*lhs_constructor.name.as_str() == "Some" && !is_refutable(cx, &pat_args[0]) &&
if method_name.node == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
lhs_constructor.name == "Some" && !is_refutable(cx, &pat_args[0]) &&
!is_iterator_used_after_while_let(cx, iter_expr) {
let iterator = snippet(cx, method_args[0].span, "_");
let loop_var = snippet(cx, pat_args[0].span, "_");
Expand All @@ -409,7 +409,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_stmt(&mut self, cx: &LateContext<'a, 'tcx>, stmt: &'tcx Stmt) {
if let StmtSemi(ref expr, _) = stmt.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) {
span_lint(cx,
UNUSED_COLLECT,
Expand Down Expand Up @@ -579,10 +579,10 @@ fn is_len_call(expr: &Expr, var: &Name) -> bool {
if_let_chain! {[
let ExprMethodCall(method, _, ref len_args) = expr.node,
len_args.len() == 1,
&*method.node.as_str() == "len",
method.node == "len",
let ExprPath(QPath::Resolved(_, ref path)) = len_args[0].node,
path.segments.len() == 1,
&path.segments[0].name == var
path.segments[0].name == *var
], {
return true;
}}
Expand Down Expand Up @@ -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 {
// just the receiver, no arguments
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
if method_name == "iter" || method_name == "iter_mut" {
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) {
let method_call = ty::MethodCall::expr(arg.id);
Expand All @@ -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();
assert_eq!(fn_arg_tys.skip_binder().len(), 1);
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 {
let object = snippet(cx, args[0].span, "_");
span_lint_and_sugg(cx,
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/map_clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
// call to .map()
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 {
ExprClosure(_, ref decl, closure_eid, _) => {
let body = cx.tcx.hir.body(closure_eid);
Expand All @@ -53,7 +53,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
}
// explicit clone() calls ( .map(|x| x.clone()) )
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 &&
match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) &&
expr_eq_name(&clone_args[0], arg_ident)
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ fn check_single_match_opt_like(
};

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);
}
}
Expand Down
14 changes: 7 additions & 7 deletions clippy_lints/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,14 +607,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
lint_or_fun_call(cx, expr, &name.node.as_str(), args);

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);
}

match self_ty.sty {
ty::TyRef(_, ty) if ty.ty.sty == ty::TyStr => {
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]);
}
}
Expand Down Expand Up @@ -646,7 +646,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
], {
// check missing trait implementations
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 &&
out_type.matches(&sig.decl.output) &&
self_kind.matches(&first_arg_ty, &first_arg, &self_ty, false) {
Expand Down Expand Up @@ -683,7 +683,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
}

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)) {
span_lint(cx,
NEW_RET_NO_SELF,
Expand Down Expand Up @@ -712,7 +712,7 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:

if name == "unwrap_or" {
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) {
let arg_ty = cx.tables.expr_ty(arg);
Expand Down Expand Up @@ -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 &*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())
} else {
None
Expand Down Expand Up @@ -1209,7 +1209,7 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
arg_char.len() == 1,
let hir::ExprPath(ref qpath) = fun.node,
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]));

Expand Down
Loading