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
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
@@ -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,
2 changes: 1 addition & 1 deletion clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}
2 changes: 1 addition & 1 deletion clippy_lints/src/blacklisted_name.rs
Original file line number Diff line number Diff line change
@@ -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,
2 changes: 1 addition & 1 deletion clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
@@ -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)));
}
}
4 changes: 2 additions & 2 deletions clippy_lints/src/entry.rs
Original file line number Diff line number Diff line change
@@ -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];
@@ -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])
], {
2 changes: 1 addition & 1 deletion clippy_lints/src/enum_variants.rs
Original file line number Diff line number Diff line change
@@ -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,
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., `&&`,
@@ -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)]);
}
)
}
_ => {}
}
}
}
}
}
2 changes: 1 addition & 1 deletion clippy_lints/src/format.rs
Original file line number Diff line number Diff line change
@@ -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,
14 changes: 7 additions & 7 deletions clippy_lints/src/len_zero.rs
Original file line number Diff line number Diff line change
@@ -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 &&
{
@@ -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 &&
{
@@ -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`",
@@ -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
4 changes: 2 additions & 2 deletions clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
@@ -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));
}
}
@@ -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);
16 changes: 8 additions & 8 deletions clippy_lints/src/loops.rs
Original file line number Diff line number Diff line change
@@ -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, "_");
@@ -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,
@@ -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;
}}
@@ -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);
@@ -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,
4 changes: 2 additions & 2 deletions clippy_lints/src/map_clone.rs
Original file line number Diff line number Diff line change
@@ -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);
@@ -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)
2 changes: 1 addition & 1 deletion clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
14 changes: 7 additions & 7 deletions clippy_lints/src/methods.rs
Original file line number Diff line number Diff line change
@@ -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]);
}
}
@@ -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) {
@@ -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,
@@ -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);
@@ -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
@@ -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]));

Loading