mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 14:25:24 +00:00
Use span_lint_and_sugg
This commit is contained in:
parent
88101d5b78
commit
745233f3ab
@ -15,7 +15,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use utils::{in_macro, snippet_block, span_lint_and_then};
|
use utils::{in_macro, snippet_block, span_lint_and_then, span_lint_and_sugg};
|
||||||
use utils::sugg::Sugg;
|
use utils::sugg::Sugg;
|
||||||
|
|
||||||
/// **What it does:** Checks for nested `if` statements which can be collapsed
|
/// **What it does:** Checks for nested `if` statements which can be collapsed
|
||||||
@ -108,12 +108,12 @@ fn check_collapsible_maybe_if_let(cx: &EarlyContext, else_: &ast::Expr) {
|
|||||||
], {
|
], {
|
||||||
match else_.node {
|
match else_.node {
|
||||||
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
|
ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) => {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
COLLAPSIBLE_IF,
|
COLLAPSIBLE_IF,
|
||||||
block.span,
|
block.span,
|
||||||
"this `else { if .. }` block can be collapsed", |db| {
|
"this `else { if .. }` block can be collapsed",
|
||||||
db.span_suggestion(block.span, "try", snippet_block(cx, else_.span, "..").into_owned());
|
"try",
|
||||||
});
|
snippet_block(cx, else_.span, "..").into_owned());
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use rustc::ty;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::ast::{Lit, LitKind, Name};
|
use syntax::ast::{Lit, LitKind, Name};
|
||||||
use syntax::codemap::{Span, Spanned};
|
use syntax::codemap::{Span, Spanned};
|
||||||
use utils::{get_item_name, in_macro, snippet, span_lint, span_lint_and_then, walk_ptrs_ty};
|
use utils::{get_item_name, in_macro, snippet, span_lint, span_lint_and_sugg, walk_ptrs_ty};
|
||||||
|
|
||||||
/// **What it does:** Checks for getting the length of something via `.len()`
|
/// **What it does:** Checks for getting the length of something via `.len()`
|
||||||
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
/// just to compare to zero, and suggests using `.is_empty()` where applicable.
|
||||||
@ -171,11 +171,9 @@ fn check_cmp(cx: &LateContext, span: Span, left: &Expr, right: &Expr, op: &str)
|
|||||||
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 == "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_sugg(cx, LEN_ZERO, span, "length comparison to zero",
|
||||||
db.span_suggestion(span,
|
"using `is_empty` is more concise:",
|
||||||
"using `is_empty` is more concise:",
|
format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")));
|
||||||
format!("{}{}.is_empty()", op, snippet(cx, args[0].span, "_")));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,16 +377,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
// 1) it was ugly with big bodies;
|
// 1) it was ugly with big bodies;
|
||||||
// 2) it was not indented properly;
|
// 2) it was not indented properly;
|
||||||
// 3) it wasn’t very smart (see #675).
|
// 3) it wasn’t very smart (see #675).
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
WHILE_LET_LOOP,
|
WHILE_LET_LOOP,
|
||||||
expr.span,
|
expr.span,
|
||||||
"this loop could be written as a `while let` loop",
|
"this loop could be written as a `while let` loop",
|
||||||
|db| {
|
"try",
|
||||||
let sug = format!("while let {} = {} {{ .. }}",
|
format!("while let {} = {} {{ .. }}",
|
||||||
snippet(cx, arms[0].pats[0].span, ".."),
|
snippet(cx, arms[0].pats[0].span, ".."),
|
||||||
snippet(cx, matchexpr.span, ".."));
|
snippet(cx, matchexpr.span, "..")));
|
||||||
db.span_suggestion(expr.span, "try", sug);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -405,13 +403,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
!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, "_");
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
WHILE_LET_ON_ITERATOR,
|
WHILE_LET_ON_ITERATOR,
|
||||||
expr.span,
|
expr.span,
|
||||||
"this loop could be written as a `for` loop",
|
"this loop could be written as a `for` loop",
|
||||||
|db| {
|
"try",
|
||||||
db.span_suggestion(expr.span, "try", format!("for {} in {} {{ .. }}", loop_var, iterator));
|
format!("for {} in {} {{ .. }}", loop_var, iterator));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use std::collections::Bound;
|
|||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block, walk_ptrs_ty,
|
use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, span_lint_and_sugg, in_external_macro, expr_block, walk_ptrs_ty,
|
||||||
is_expn_of, remove_blocks};
|
is_expn_of, remove_blocks};
|
||||||
use utils::sugg::Sugg;
|
use utils::sugg::Sugg;
|
||||||
|
|
||||||
@ -210,20 +210,17 @@ fn report_single_match_single_pattern(cx: &LateContext, ex: &Expr, arms: &[Arm],
|
|||||||
SINGLE_MATCH
|
SINGLE_MATCH
|
||||||
};
|
};
|
||||||
let els_str = els.map_or(String::new(), |els| format!(" else {}", expr_block(cx, els, None, "..")));
|
let els_str = els.map_or(String::new(), |els| format!(" else {}", expr_block(cx, els, None, "..")));
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
lint,
|
lint,
|
||||||
expr.span,
|
expr.span,
|
||||||
"you seem to be trying to use match for destructuring a single pattern. Consider using `if \
|
"you seem to be trying to use match for destructuring a single pattern. Consider using `if \
|
||||||
let`",
|
let`",
|
||||||
|db| {
|
"try this",
|
||||||
db.span_suggestion(expr.span,
|
format!("if let {} = {} {}{}",
|
||||||
"try this",
|
snippet(cx, arms[0].pats[0].span, ".."),
|
||||||
format!("if let {} = {} {}{}",
|
snippet(cx, ex.span, ".."),
|
||||||
snippet(cx, arms[0].pats[0].span, ".."),
|
expr_block(cx, &arms[0].body, None, ".."),
|
||||||
snippet(cx, ex.span, ".."),
|
els_str));
|
||||||
expr_block(cx, &arms[0].body, None, ".."),
|
|
||||||
els_str));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, ty: Ty, els: Option<&Expr>) {
|
fn check_single_match_opt_like(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr, ty: Ty, els: Option<&Expr>) {
|
||||||
|
@ -8,7 +8,7 @@ use std::borrow::Cow;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, match_path, match_trait_method,
|
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, match_path, match_trait_method,
|
||||||
match_type, method_chain_args, return_ty, same_tys, snippet, span_lint, span_lint_and_then,
|
match_type, method_chain_args, return_ty, same_tys, snippet, span_lint, span_lint_and_then, span_lint_and_sugg,
|
||||||
span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, last_path_segment, single_segment_path,
|
span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, last_path_segment, single_segment_path,
|
||||||
match_def_path, is_self, is_self_ty, iter_input_pats, match_path_old};
|
match_def_path, is_self, is_self_ty, iter_input_pats, match_path_old};
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
@ -725,15 +725,12 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
|
|||||||
};
|
};
|
||||||
|
|
||||||
if implements_trait(cx, arg_ty, default_trait_id, &[]) {
|
if implements_trait(cx, arg_ty, default_trait_id, &[]) {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
OR_FUN_CALL,
|
OR_FUN_CALL,
|
||||||
span,
|
span,
|
||||||
&format!("use of `{}` followed by a call to `{}`", name, path),
|
&format!("use of `{}` followed by a call to `{}`", name, path),
|
||||||
|db| {
|
"try this",
|
||||||
db.span_suggestion(span,
|
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
||||||
"try this",
|
|
||||||
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -791,15 +788,12 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
|
|||||||
(false, true) => snippet(cx, fun_span, ".."),
|
(false, true) => snippet(cx, fun_span, ".."),
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
OR_FUN_CALL,
|
OR_FUN_CALL,
|
||||||
span,
|
span,
|
||||||
&format!("use of `{}` followed by a function call", name),
|
&format!("use of `{}` followed by a function call", name),
|
||||||
|db| {
|
"try this",
|
||||||
db.span_suggestion(span,
|
format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg));
|
||||||
"try this",
|
|
||||||
format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.len() == 2 {
|
if args.len() == 2 {
|
||||||
@ -865,14 +859,12 @@ fn lint_string_extend(cx: &LateContext, expr: &hir::Expr, args: &[hir::Expr]) {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint_and_then(cx, STRING_EXTEND_CHARS, expr.span, "calling `.extend(_.chars())`", |db| {
|
span_lint_and_sugg(cx, STRING_EXTEND_CHARS, expr.span, "calling `.extend(_.chars())`",
|
||||||
db.span_suggestion(expr.span,
|
"try this",
|
||||||
"try this",
|
format!("{}.push_str({}{})",
|
||||||
format!("{}.push_str({}{})",
|
snippet(cx, args[0].span, "_"),
|
||||||
snippet(cx, args[0].span, "_"),
|
ref_str,
|
||||||
ref_str,
|
snippet(cx, target.span, "_")));
|
||||||
snippet(cx, target.span, "_")));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,20 +943,17 @@ fn lint_get_unwrap(cx: &LateContext, expr: &hir::Expr, get_args: &[hir::Expr], i
|
|||||||
|
|
||||||
let mut_str = if is_mut { "_mut" } else { "" };
|
let mut_str = if is_mut { "_mut" } else { "" };
|
||||||
let borrow_str = if is_mut { "&mut " } else { "&" };
|
let borrow_str = if is_mut { "&mut " } else { "&" };
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
GET_UNWRAP,
|
GET_UNWRAP,
|
||||||
expr.span,
|
expr.span,
|
||||||
&format!("called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise",
|
&format!("called `.get{0}().unwrap()` on a {1}. Using `[]` is more clear and more concise",
|
||||||
mut_str,
|
mut_str,
|
||||||
caller_type),
|
caller_type),
|
||||||
|db| {
|
"try this",
|
||||||
db.span_suggestion(expr.span,
|
format!("{}{}[{}]",
|
||||||
"try this",
|
borrow_str,
|
||||||
format!("{}{}[{}]",
|
snippet(cx, get_args[0].span, "_"),
|
||||||
borrow_str,
|
snippet(cx, get_args[1].span, "_")));
|
||||||
snippet(cx, get_args[0].span, "_"),
|
|
||||||
snippet(cx, get_args[1].span, "_")));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lint_iter_skip_next(cx: &LateContext, expr: &hir::Expr) {
|
fn lint_iter_skip_next(cx: &LateContext, expr: &hir::Expr) {
|
||||||
@ -1216,19 +1205,15 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
CHARS_NEXT_CMP,
|
CHARS_NEXT_CMP,
|
||||||
expr.span,
|
expr.span,
|
||||||
"you should use the `starts_with` method",
|
"you should use the `starts_with` method",
|
||||||
|db| {
|
"like this",
|
||||||
let sugg = format!("{}{}.starts_with({})",
|
format!("{}{}.starts_with({})",
|
||||||
if eq { "" } else { "!" },
|
if eq { "" } else { "!" },
|
||||||
snippet(cx, args[0][0].span, "_"),
|
snippet(cx, args[0][0].span, "_"),
|
||||||
snippet(cx, arg_char[0].span, "_")
|
snippet(cx, arg_char[0].span, "_")));
|
||||||
);
|
|
||||||
|
|
||||||
db.span_suggestion(expr.span, "like this", sugg);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
|
@ -6,7 +6,7 @@ use rustc::lint::*;
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use utils::{span_lint, span_lint_and_then, snippet};
|
use utils::{span_lint, span_lint_and_sugg, snippet};
|
||||||
use utils::sugg::Sugg;
|
use utils::sugg::Sugg;
|
||||||
|
|
||||||
/// **What it does:** Checks for expressions of the form `if c { true } else { false }`
|
/// **What it does:** Checks for expressions of the form `if c { true } else { false }`
|
||||||
@ -70,11 +70,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBool {
|
|||||||
snip.to_string()
|
snip.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
NEEDLESS_BOOL,
|
NEEDLESS_BOOL,
|
||||||
e.span,
|
e.span,
|
||||||
"this if-then-else expression returns a bool literal",
|
"this if-then-else expression returns a bool literal",
|
||||||
|db| { db.span_suggestion(e.span, "you can reduce it to", hint); });
|
"you can reduce it to",
|
||||||
|
hint);
|
||||||
};
|
};
|
||||||
if let ExprBlock(ref then_block) = then_block.node {
|
if let ExprBlock(ref then_block) = then_block.node {
|
||||||
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
|
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
|
||||||
@ -121,39 +122,39 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
|
|||||||
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
|
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
|
||||||
(Bool(true), Other) => {
|
(Bool(true), Other) => {
|
||||||
let hint = snippet(cx, right_side.span, "..").into_owned();
|
let hint = snippet(cx, right_side.span, "..").into_owned();
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
BOOL_COMPARISON,
|
BOOL_COMPARISON,
|
||||||
e.span,
|
e.span,
|
||||||
"equality checks against true are unnecessary",
|
"equality checks against true are unnecessary",
|
||||||
|db| { db.span_suggestion(e.span, "try simplifying it as shown:", hint); });
|
"try simplifying it as shown:",
|
||||||
|
hint);
|
||||||
},
|
},
|
||||||
(Other, Bool(true)) => {
|
(Other, Bool(true)) => {
|
||||||
let hint = snippet(cx, left_side.span, "..").into_owned();
|
let hint = snippet(cx, left_side.span, "..").into_owned();
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
BOOL_COMPARISON,
|
BOOL_COMPARISON,
|
||||||
e.span,
|
e.span,
|
||||||
"equality checks against true are unnecessary",
|
"equality checks against true are unnecessary",
|
||||||
|db| { db.span_suggestion(e.span, "try simplifying it as shown:", hint); });
|
"try simplifying it as shown:",
|
||||||
|
hint);
|
||||||
},
|
},
|
||||||
(Bool(false), Other) => {
|
(Bool(false), Other) => {
|
||||||
let hint = Sugg::hir(cx, right_side, "..");
|
let hint = Sugg::hir(cx, right_side, "..");
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
BOOL_COMPARISON,
|
BOOL_COMPARISON,
|
||||||
e.span,
|
e.span,
|
||||||
"equality checks against false can be replaced by a negation",
|
"equality checks against false can be replaced by a negation",
|
||||||
|db| {
|
"try simplifying it as shown:",
|
||||||
db.span_suggestion(e.span, "try simplifying it as shown:", (!hint).to_string());
|
(!hint).to_string());
|
||||||
});
|
|
||||||
},
|
},
|
||||||
(Other, Bool(false)) => {
|
(Other, Bool(false)) => {
|
||||||
let hint = Sugg::hir(cx, left_side, "..");
|
let hint = Sugg::hir(cx, left_side, "..");
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
BOOL_COMPARISON,
|
BOOL_COMPARISON,
|
||||||
e.span,
|
e.span,
|
||||||
"equality checks against false can be replaced by a negation",
|
"equality checks against false can be replaced by a negation",
|
||||||
|db| {
|
"try simplifying it as shown:",
|
||||||
db.span_suggestion(e.span, "try simplifying it as shown:", (!hint).to_string());
|
(!hint).to_string());
|
||||||
});
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::Def;
|
||||||
use rustc::hir::{Expr, Expr_, Stmt, StmtSemi, BlockCheckMode, UnsafeSource, BiAnd, BiOr};
|
use rustc::hir::{Expr, Expr_, Stmt, StmtSemi, BlockCheckMode, UnsafeSource, BiAnd, BiOr};
|
||||||
use utils::{in_macro, span_lint, snippet_opt, span_lint_and_then};
|
use utils::{in_macro, span_lint, snippet_opt, span_lint_and_sugg};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
/// **What it does:** Checks for statements which have no effect.
|
/// **What it does:** Checks for statements which have no effect.
|
||||||
@ -120,11 +120,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
UNNECESSARY_OPERATION,
|
UNNECESSARY_OPERATION,
|
||||||
stmt.span,
|
stmt.span,
|
||||||
"statement can be reduced",
|
"statement can be reduced",
|
||||||
|db| { db.span_suggestion(stmt.span, "replace it with", snippet); });
|
"replace it with",
|
||||||
|
snippet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use utils::{span_lint_and_then, snippet};
|
use utils::{span_lint_and_sugg, snippet};
|
||||||
|
|
||||||
/// **What it does:** Checks for operations where precedence may be unclear
|
/// **What it does:** Checks for operations where precedence may be unclear
|
||||||
/// and suggests to add parentheses. Currently it catches the following:
|
/// and suggests to add parentheses. Currently it catches the following:
|
||||||
@ -38,9 +38,8 @@ impl EarlyLintPass for Precedence {
|
|||||||
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
|
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
|
||||||
let span_sugg =
|
let span_sugg =
|
||||||
|expr: &Expr, sugg| {
|
|expr: &Expr, sugg| {
|
||||||
span_lint_and_then(cx, PRECEDENCE, expr.span, "operator precedence can trip the unwary", |db| {
|
span_lint_and_sugg(cx, PRECEDENCE, expr.span, "operator precedence can trip the unwary",
|
||||||
db.span_suggestion(expr.span, "consider parenthesizing your expression", sugg);
|
"consider parenthesizing your expression", sugg);
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !is_bit_op(op) {
|
if !is_bit_op(op) {
|
||||||
@ -80,15 +79,12 @@ impl EarlyLintPass for Precedence {
|
|||||||
LitKind::Int(..) |
|
LitKind::Int(..) |
|
||||||
LitKind::Float(..) |
|
LitKind::Float(..) |
|
||||||
LitKind::FloatUnsuffixed(..) => {
|
LitKind::FloatUnsuffixed(..) => {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
PRECEDENCE,
|
PRECEDENCE,
|
||||||
expr.span,
|
expr.span,
|
||||||
"unary minus has lower precedence than method call",
|
"unary minus has lower precedence than method call",
|
||||||
|db| {
|
"consider adding parentheses to clarify your intent",
|
||||||
db.span_suggestion(expr.span,
|
format!("-({})", snippet(cx, rhs.span, "..")));
|
||||||
"consider adding parentheses to clarify your intent",
|
|
||||||
format!("-({})", snippet(cx, rhs.span, "..")));
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use syntax::ast::{Expr, ExprKind, UnOp};
|
use syntax::ast::{Expr, ExprKind, UnOp};
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use utils::{span_lint_and_then, snippet};
|
use utils::{span_lint_and_sugg, snippet};
|
||||||
|
|
||||||
/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
|
/// **What it does:** Checks for usage of `*&` and `*&mut` in expressions.
|
||||||
///
|
///
|
||||||
@ -40,9 +40,8 @@ impl EarlyLintPass for Pass {
|
|||||||
fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
|
||||||
if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node {
|
if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.node {
|
||||||
if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node {
|
if let ExprKind::AddrOf(_, ref addrof_target) = without_parens(deref_target).node {
|
||||||
span_lint_and_then(cx, DEREF_ADDROF, e.span, "immediately dereferencing a reference", |db| {
|
span_lint_and_sugg(cx, DEREF_ADDROF, e.span, "immediately dereferencing a reference",
|
||||||
db.span_suggestion(e.span, "try this", format!("{}", snippet(cx, addrof_target.span, "_")));
|
"try this", format!("{}", snippet(cx, addrof_target.span, "_")));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use rustc::hir::*;
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use utils::SpanlessEq;
|
use utils::SpanlessEq;
|
||||||
use utils::{match_type, paths, span_lint, span_lint_and_then, walk_ptrs_ty, get_parent_expr};
|
use utils::{match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty, get_parent_expr};
|
||||||
|
|
||||||
/// **What it does:** Checks for string appends of the form `x = x + y` (without
|
/// **What it does:** Checks for string appends of the form `x = x + y` (without
|
||||||
/// `let`!).
|
/// `let`!).
|
||||||
@ -147,15 +147,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
|
|||||||
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(args[0].span) {
|
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
STRING_LIT_AS_BYTES,
|
STRING_LIT_AS_BYTES,
|
||||||
e.span,
|
e.span,
|
||||||
"calling `as_bytes()` on a string literal",
|
"calling `as_bytes()` on a string literal",
|
||||||
|db| {
|
"consider using a byte string literal instead",
|
||||||
let sugg = format!("b{}", snippet(cx, args[0].span, r#""foo""#));
|
format!("b{}", snippet(cx, args[0].span, r#""foo""#)));
|
||||||
db.span_suggestion(e.span, "consider using a byte string literal instead", sugg);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use std::cmp::Ordering;
|
|||||||
use syntax::ast::{IntTy, UintTy, FloatTy};
|
use syntax::ast::{IntTy, UintTy, FloatTy};
|
||||||
use syntax::attr::IntType;
|
use syntax::attr::IntType;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, span_help_and_lint, span_lint, span_lint_and_then,
|
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, span_help_and_lint, span_lint, span_lint_and_sugg,
|
||||||
opt_def_id, last_path_segment, type_size};
|
opt_def_id, last_path_segment, type_size};
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
|
|
||||||
@ -210,15 +210,12 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
|
|||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
BORROWED_BOX,
|
BORROWED_BOX,
|
||||||
ast_ty.span,
|
ast_ty.span,
|
||||||
"you seem to be trying to use `&Box<T>`. Consider using just `&T`",
|
"you seem to be trying to use `&Box<T>`. Consider using just `&T`",
|
||||||
|db| {
|
"try",
|
||||||
db.span_suggestion(ast_ty.span,
|
format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, ".."))
|
||||||
"try",
|
|
||||||
format!("&{}{}{}", ltopt, mutopt, &snippet(cx, inner.span, "..")));
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
return; // don't recurse into the type
|
return; // don't recurse into the type
|
||||||
}};
|
}};
|
||||||
|
@ -3,7 +3,7 @@ use rustc::lint::*;
|
|||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc_const_eval::ConstContext;
|
use rustc_const_eval::ConstContext;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{higher, is_copy, snippet, span_lint_and_then};
|
use utils::{higher, is_copy, snippet, span_lint_and_sugg};
|
||||||
|
|
||||||
/// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would
|
/// **What it does:** Checks for usage of `&vec![..]` when using `&[..]` would
|
||||||
/// be possible.
|
/// be possible.
|
||||||
@ -80,11 +80,12 @@ fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint_and_then(cx,
|
span_lint_and_sugg(cx,
|
||||||
USELESS_VEC,
|
USELESS_VEC,
|
||||||
span,
|
span,
|
||||||
"useless use of `vec!`",
|
"useless use of `vec!`",
|
||||||
|db| { db.span_suggestion(span, "you can use a slice directly", snippet); });
|
"you can use a slice directly",
|
||||||
|
snippet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the item type of the vector (ie. the `T` in `Vec<T>`).
|
/// Return the item type of the vector (ie. the `T` in `Vec<T>`).
|
||||||
|
Loading…
Reference in New Issue
Block a user