Use span_lint_and_sugg

This commit is contained in:
Seo Sanghyeon 2017-06-22 03:04:04 +09:00
parent 88101d5b78
commit 745233f3ab
12 changed files with 91 additions and 122 deletions

View File

@ -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());
} }
_ => (), _ => (),
} }

View File

@ -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, "_")));
});
} }
} }
} }

View File

@ -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 wasnt very smart (see #675). // 3) it wasnt 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));
});
} }
} }
} }

View File

@ -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>) {

View File

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

View File

@ -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());
});
}, },
_ => (), _ => (),
} }

View File

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

View File

@ -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, "..")));
});
}, },
_ => (), _ => (),
} }

View File

@ -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, "_")));
});
} }
} }
} }

View File

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

View File

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

View File

@ -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>`).