mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Upgrade Rust to rustc 1.5.0-nightly (cff041170
2015-09-17)
LintPass was split and ExprParen was removed from the HIR Fixes #338
This commit is contained in:
parent
862c195fa1
commit
f4da7d09d2
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clippy"
|
||||
version = "0.0.14"
|
||||
version = "0.0.15"
|
||||
authors = [
|
||||
"Manish Goregaokar <manishsmail@gmail.com>",
|
||||
"Andre Bogus <bogusandre@gmail.com>",
|
||||
|
@ -29,15 +29,17 @@ impl LintPass for ApproxConstant {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(APPROX_CONSTANT)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for ApproxConstant {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let &ExprLit(ref lit) = &e.node {
|
||||
check_lit(cx, lit, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lit(cx: &Context, lit: &Lit, e: &Expr) {
|
||||
fn check_lit(cx: &LateContext, lit: &Lit, e: &Expr) {
|
||||
match lit.node {
|
||||
LitFloat(ref str, TyF32) => check_known_consts(cx, e, str, "f32"),
|
||||
LitFloat(ref str, TyF64) => check_known_consts(cx, e, str, "f64"),
|
||||
@ -47,7 +49,7 @@ fn check_lit(cx: &Context, lit: &Lit, e: &Expr) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_known_consts(cx: &Context, e: &Expr, str: &str, module: &str) {
|
||||
fn check_known_consts(cx: &LateContext, e: &Expr, str: &str, module: &str) {
|
||||
if let Ok(value) = str.parse::<f64>() {
|
||||
for &(constant, name) in KNOWN_CONSTS {
|
||||
if !within_epsilon(constant, value) { continue; }
|
||||
|
13
src/attrs.rs
13
src/attrs.rs
@ -19,20 +19,22 @@ impl LintPass for AttrPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(INLINE_ALWAYS)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
impl LateLintPass for AttrPass {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
if is_relevant_item(item) {
|
||||
check_attrs(cx, item.span, &item.ident, &item.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &Context, item: &ImplItem) {
|
||||
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
|
||||
if is_relevant_impl(item) {
|
||||
check_attrs(cx, item.span, &item.ident, &item.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &Context, item: &TraitItem) {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
|
||||
if is_relevant_trait(item) {
|
||||
check_attrs(cx, item.span, &item.ident, &item.attrs)
|
||||
}
|
||||
@ -75,8 +77,7 @@ fn is_relevant_block(block: &Block) -> bool {
|
||||
fn is_relevant_expr(expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprBlock(ref block) => is_relevant_block(block),
|
||||
ExprRet(Some(ref e)) | ExprParen(ref e) =>
|
||||
is_relevant_expr(e),
|
||||
ExprRet(Some(ref e)) => is_relevant_expr(e),
|
||||
ExprRet(None) | ExprBreak(_) => false,
|
||||
ExprCall(ref path_expr, _) => {
|
||||
if let ExprPath(_, ref path) = path_expr.node {
|
||||
@ -87,7 +88,7 @@ fn is_relevant_expr(expr: &Expr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_attrs(cx: &Context, span: Span, ident: &Ident,
|
||||
fn check_attrs(cx: &LateContext, span: Span, ident: &Ident,
|
||||
attrs: &[Attribute]) {
|
||||
if in_macro(cx, span) { return; }
|
||||
|
||||
|
@ -54,8 +54,10 @@ impl LintPass for BitMask {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(BAD_BIT_MASK, INEFFECTIVE_BIT_MASK)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for BitMask {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let ExprBinary(ref cmp, ref left, ref right) = e.node {
|
||||
if is_comparison_binop(cmp.node) {
|
||||
fetch_int_literal(cx, right).map_or_else(||
|
||||
@ -82,9 +84,8 @@ fn invert_cmp(cmp : BinOp_) -> BinOp_ {
|
||||
}
|
||||
|
||||
|
||||
fn check_compare(cx: &Context, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u64, span: &Span) {
|
||||
fn check_compare(cx: &LateContext, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u64, span: &Span) {
|
||||
match bit_op.node {
|
||||
ExprParen(ref subexp) => check_compare(cx, subexp, cmp_op, cmp_value, span),
|
||||
ExprBinary(ref op, ref left, ref right) => {
|
||||
if op.node != BiBitAnd && op.node != BiBitOr { return; }
|
||||
fetch_int_literal(cx, right).or_else(|| fetch_int_literal(
|
||||
@ -95,7 +96,7 @@ fn check_compare(cx: &Context, bit_op: &Expr, cmp_op: BinOp_, cmp_value: u64, sp
|
||||
}
|
||||
}
|
||||
|
||||
fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
||||
fn check_bit_mask(cx: &LateContext, bit_op: BinOp_, cmp_op: BinOp_,
|
||||
mask_value: u64, cmp_value: u64, span: &Span) {
|
||||
match cmp_op {
|
||||
BiEq | BiNe => match bit_op {
|
||||
@ -163,7 +164,7 @@ fn check_bit_mask(cx: &Context, bit_op: BinOp_, cmp_op: BinOp_,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
fn check_ineffective_lt(cx: &LateContext, span: Span, m: u64, c: u64, op: &str) {
|
||||
if c.is_power_of_two() && m < c {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||
@ -171,7 +172,7 @@ fn check_ineffective_lt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ineffective_gt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
fn check_ineffective_gt(cx: &LateContext, span: Span, m: u64, c: u64, op: &str) {
|
||||
if (c + 1).is_power_of_two() && m <= c {
|
||||
span_lint(cx, INEFFECTIVE_BIT_MASK, span, &format!(
|
||||
"ineffective bit mask: `x {} {}` compared to `{}`, is the same as x compared directly",
|
||||
@ -179,7 +180,7 @@ fn check_ineffective_gt(cx: &Context, span: Span, m: u64, c: u64, op: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_int_literal(cx: &Context, lit : &Expr) -> Option<u64> {
|
||||
fn fetch_int_literal(cx: &LateContext, lit : &Expr) -> Option<u64> {
|
||||
match lit.node {
|
||||
ExprLit(ref lit_ptr) => {
|
||||
if let &LitInt(value, _) = &lit_ptr.node {
|
||||
|
@ -32,15 +32,17 @@ impl LintPass for CollapsibleIf {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(COLLAPSIBLE_IF)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for CollapsibleIf {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if !in_macro(cx, expr.span) {
|
||||
check_if(cx, expr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_if(cx: &Context, e: &Expr) {
|
||||
fn check_if(cx: &LateContext, e: &Expr) {
|
||||
if let ExprIf(ref check, ref then, None) = e.node {
|
||||
if let Some(&Expr{ node: ExprIf(ref check_inner, ref content, None), span: sp, ..}) =
|
||||
single_stmt_of_block(then) {
|
||||
@ -63,7 +65,7 @@ fn requires_brackets(e: &Expr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_to_string(cx: &Context, e: &Expr) -> String {
|
||||
fn check_to_string(cx: &LateContext, e: &Expr) -> String {
|
||||
if requires_brackets(e) {
|
||||
format!("({})", snippet(cx, e.span, ".."))
|
||||
} else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![allow(cast_possible_truncation)]
|
||||
|
||||
use rustc::lint::Context;
|
||||
use rustc::lint::LateContext;
|
||||
use rustc::middle::const_eval::lookup_const_by_id;
|
||||
use rustc::middle::def::PathResolution;
|
||||
use rustc::middle::def::Def::*;
|
||||
@ -287,27 +287,26 @@ fn sub_int(l: u64, lty: LitIntType, r: u64, rty: LitIntType, neg: bool) ->
|
||||
}
|
||||
|
||||
|
||||
pub fn constant(lcx: &Context, e: &Expr) -> Option<(Constant, bool)> {
|
||||
let mut cx = ConstEvalContext { lcx: Some(lcx), needed_resolution: false };
|
||||
pub fn constant(lcx: &LateContext, e: &Expr) -> Option<(Constant, bool)> {
|
||||
let mut cx = ConstEvalLateContext { lcx: Some(lcx), needed_resolution: false };
|
||||
cx.expr(e).map(|cst| (cst, cx.needed_resolution))
|
||||
}
|
||||
|
||||
pub fn constant_simple(e: &Expr) -> Option<Constant> {
|
||||
let mut cx = ConstEvalContext { lcx: None, needed_resolution: false };
|
||||
let mut cx = ConstEvalLateContext { lcx: None, needed_resolution: false };
|
||||
cx.expr(e)
|
||||
}
|
||||
|
||||
struct ConstEvalContext<'c, 'cc: 'c> {
|
||||
lcx: Option<&'c Context<'c, 'cc>>,
|
||||
struct ConstEvalLateContext<'c, 'cc: 'c> {
|
||||
lcx: Option<&'c LateContext<'c, 'cc>>,
|
||||
needed_resolution: bool
|
||||
}
|
||||
|
||||
impl<'c, 'cc> ConstEvalContext<'c, 'cc> {
|
||||
impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
||||
|
||||
/// simple constant folding: Insert an expression, get a constant or none.
|
||||
fn expr(&mut self, e: &Expr) -> Option<Constant> {
|
||||
match e.node {
|
||||
ExprParen(ref inner) => self.expr(inner),
|
||||
ExprPath(_, _) => self.fetch_path(e),
|
||||
ExprBlock(ref block) => self.block(block),
|
||||
ExprIf(ref cond, ref then, ref otherwise) =>
|
||||
|
10
src/eq_op.rs
10
src/eq_op.rs
@ -19,8 +19,10 @@ impl LintPass for EqOp {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(EQ_OP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for EqOp {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let ExprBinary(ref op, ref left, ref right) = e.node {
|
||||
if is_cmp_or_bit(op) && is_exp_equal(cx, left, right) {
|
||||
span_lint(cx, EQ_OP, e.span, &format!(
|
||||
@ -31,7 +33,7 @@ impl LintPass for EqOp {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_exp_equal(cx: &Context, left : &Expr, right : &Expr) -> bool {
|
||||
pub fn is_exp_equal(cx: &LateContext, left : &Expr, right : &Expr) -> bool {
|
||||
if let (Some(l), Some(r)) = (constant(cx, left), constant(cx, right)) {
|
||||
if l == r {
|
||||
return true;
|
||||
@ -42,8 +44,6 @@ pub fn is_exp_equal(cx: &Context, left : &Expr, right : &Expr) -> bool {
|
||||
&ExprField(ref rfexp, ref rfident)) =>
|
||||
lfident.node == rfident.node && is_exp_equal(cx, lfexp, rfexp),
|
||||
(&ExprLit(ref l), &ExprLit(ref r)) => l.node == r.node,
|
||||
(&ExprParen(ref lparen), _) => is_exp_equal(cx, lparen, right),
|
||||
(_, &ExprParen(ref rparen)) => is_exp_equal(cx, left, rparen),
|
||||
(&ExprPath(ref lqself, ref lsubpath),
|
||||
&ExprPath(ref rqself, ref rsubpath)) =>
|
||||
both(lqself, rqself, is_qself_equal) &&
|
||||
@ -57,7 +57,7 @@ pub fn is_exp_equal(cx: &Context, left : &Expr, right : &Expr) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_exps_equal(cx: &Context, left : &[P<Expr>], right : &[P<Expr>]) -> bool {
|
||||
fn is_exps_equal(cx: &LateContext, left : &[P<Expr>], right : &[P<Expr>]) -> bool {
|
||||
over(left, right, |l, r| is_exp_equal(cx, l, r))
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,10 @@ impl LintPass for EtaPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(REDUNDANT_CLOSURE)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for EtaPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
match expr.node {
|
||||
ExprCall(_, ref args) |
|
||||
ExprMethodCall(_, _, ref args) => {
|
||||
@ -30,11 +32,11 @@ impl LintPass for EtaPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_adjusted(cx: &Context, e: &Expr) -> bool {
|
||||
fn is_adjusted(cx: &LateContext, e: &Expr) -> bool {
|
||||
cx.tcx.tables.borrow().adjustments.get(&e.id).is_some()
|
||||
}
|
||||
|
||||
fn check_closure(cx: &Context, expr: &Expr) {
|
||||
fn check_closure(cx: &LateContext, expr: &Expr) {
|
||||
if let ExprClosure(_, ref decl, ref blk) = expr.node {
|
||||
if !blk.stmts.is_empty() {
|
||||
// || {foo(); bar()}; can't be reduced here
|
||||
|
@ -16,8 +16,10 @@ impl LintPass for IdentityOp {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(IDENTITY_OP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for IdentityOp {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if in_macro(cx, e.span) { return; }
|
||||
if let ExprBinary(ref cmp, ref left, ref right) = e.node {
|
||||
match cmp.node {
|
||||
@ -44,7 +46,7 @@ impl LintPass for IdentityOp {
|
||||
}
|
||||
|
||||
|
||||
fn check(cx: &Context, e: &Expr, m: i8, span: Span, arg: Span) {
|
||||
fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) {
|
||||
if let Some(ConstantInt(v, ty)) = constant_simple(e) {
|
||||
if match m {
|
||||
0 => v == 0,
|
||||
|
@ -24,8 +24,10 @@ impl LintPass for LenZero {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(LEN_ZERO, LEN_WITHOUT_IS_EMPTY)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
impl LateLintPass for LenZero {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
match item.node {
|
||||
ItemTrait(_, _, _, ref trait_items) =>
|
||||
check_trait_items(cx, item, trait_items),
|
||||
@ -35,7 +37,7 @@ impl LintPass for LenZero {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprBinary(Spanned{node: cmp, ..}, ref left, ref right) =
|
||||
expr.node {
|
||||
match cmp {
|
||||
@ -47,7 +49,7 @@ impl LintPass for LenZero {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_items(cx: &Context, item: &Item, trait_items: &[P<TraitItem>]) {
|
||||
fn check_trait_items(cx: &LateContext, item: &Item, trait_items: &[P<TraitItem>]) {
|
||||
fn is_named_self(item: &TraitItem, name: &str) -> bool {
|
||||
item.ident.name == name && if let MethodTraitItem(ref sig, _) =
|
||||
item.node { is_self_sig(sig) } else { false }
|
||||
@ -66,7 +68,7 @@ fn check_trait_items(cx: &Context, item: &Item, trait_items: &[P<TraitItem>]) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_impl_items(cx: &Context, item: &Item, impl_items: &[P<ImplItem>]) {
|
||||
fn check_impl_items(cx: &LateContext, item: &Item, impl_items: &[P<ImplItem>]) {
|
||||
fn is_named_self(item: &ImplItem, name: &str) -> bool {
|
||||
item.ident.name == name && if let MethodImplItem(ref sig, _) =
|
||||
item.node { is_self_sig(sig) } else { false }
|
||||
@ -92,7 +94,7 @@ fn is_self_sig(sig: &MethodSig) -> bool {
|
||||
false } else { sig.decl.inputs.len() == 1 }
|
||||
}
|
||||
|
||||
fn check_cmp(cx: &Context, 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
|
||||
if let Some(name) = get_item_name(cx, left) {
|
||||
if name == "is_empty" { return; }
|
||||
@ -106,7 +108,7 @@ fn check_cmp(cx: &Context, span: Span, left: &Expr, right: &Expr, op: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_len_zero(cx: &Context, span: Span, method: &SpannedIdent,
|
||||
fn check_len_zero(cx: &LateContext, span: Span, method: &SpannedIdent,
|
||||
args: &[P<Expr>], lit: &Lit, op: &str) {
|
||||
if let Spanned{node: LitInt(0, _), ..} = *lit {
|
||||
if method.node.name == "len" && args.len() == 1 &&
|
||||
@ -119,9 +121,9 @@ fn check_len_zero(cx: &Context, span: Span, method: &SpannedIdent,
|
||||
}
|
||||
|
||||
/// check if this type has an is_empty method
|
||||
fn has_is_empty(cx: &Context, expr: &Expr) -> bool {
|
||||
fn has_is_empty(cx: &LateContext, expr: &Expr) -> bool {
|
||||
/// get a ImplOrTraitItem and return true if it matches is_empty(self)
|
||||
fn is_is_empty(cx: &Context, id: &ImplOrTraitItemId) -> bool {
|
||||
fn is_is_empty(cx: &LateContext, id: &ImplOrTraitItemId) -> bool {
|
||||
if let &MethodTraitItemId(def_id) = id {
|
||||
if let ty::MethodTraitItem(ref method) =
|
||||
cx.tcx.impl_or_trait_item(def_id) {
|
||||
@ -132,7 +134,7 @@ fn has_is_empty(cx: &Context, expr: &Expr) -> bool {
|
||||
}
|
||||
|
||||
/// check the inherent impl's items for an is_empty(self) method
|
||||
fn has_is_empty_impl(cx: &Context, id: &DefId) -> bool {
|
||||
fn has_is_empty_impl(cx: &LateContext, id: &DefId) -> bool {
|
||||
let impl_items = cx.tcx.impl_items.borrow();
|
||||
cx.tcx.inherent_impls.borrow().get(id).map_or(false,
|
||||
|ids| ids.iter().any(|iid| impl_items.get(iid).map_or(false,
|
||||
|
67
src/lib.rs
67
src/lib.rs
@ -18,7 +18,6 @@ extern crate collections;
|
||||
extern crate unicode_normalization;
|
||||
|
||||
use rustc::plugin::Registry;
|
||||
use rustc::lint::LintPassObject;
|
||||
|
||||
#[macro_use]
|
||||
pub mod utils;
|
||||
@ -54,39 +53,39 @@ mod reexport {
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_lint_pass(box types::TypePass as LintPassObject);
|
||||
reg.register_lint_pass(box misc::TopLevelRefPass as LintPassObject);
|
||||
reg.register_lint_pass(box misc::CmpNan as LintPassObject);
|
||||
reg.register_lint_pass(box eq_op::EqOp as LintPassObject);
|
||||
reg.register_lint_pass(box bit_mask::BitMask as LintPassObject);
|
||||
reg.register_lint_pass(box ptr_arg::PtrArg as LintPassObject);
|
||||
reg.register_lint_pass(box needless_bool::NeedlessBool as LintPassObject);
|
||||
reg.register_lint_pass(box approx_const::ApproxConstant as LintPassObject);
|
||||
reg.register_lint_pass(box misc::FloatCmp as LintPassObject);
|
||||
reg.register_lint_pass(box precedence::Precedence as LintPassObject);
|
||||
reg.register_lint_pass(box eta_reduction::EtaPass as LintPassObject);
|
||||
reg.register_lint_pass(box identity_op::IdentityOp as LintPassObject);
|
||||
reg.register_lint_pass(box mut_mut::MutMut as LintPassObject);
|
||||
reg.register_lint_pass(box len_zero::LenZero as LintPassObject);
|
||||
reg.register_lint_pass(box misc::CmpOwned as LintPassObject);
|
||||
reg.register_lint_pass(box attrs::AttrPass as LintPassObject);
|
||||
reg.register_lint_pass(box collapsible_if::CollapsibleIf as LintPassObject);
|
||||
reg.register_lint_pass(box misc::ModuloOne as LintPassObject);
|
||||
reg.register_lint_pass(box unicode::Unicode as LintPassObject);
|
||||
reg.register_lint_pass(box strings::StringAdd as LintPassObject);
|
||||
reg.register_lint_pass(box returns::ReturnPass as LintPassObject);
|
||||
reg.register_lint_pass(box methods::MethodsPass as LintPassObject);
|
||||
reg.register_lint_pass(box shadow::ShadowPass as LintPassObject);
|
||||
reg.register_lint_pass(box types::LetPass as LintPassObject);
|
||||
reg.register_lint_pass(box types::UnitCmp as LintPassObject);
|
||||
reg.register_lint_pass(box loops::LoopsPass as LintPassObject);
|
||||
reg.register_lint_pass(box lifetimes::LifetimePass as LintPassObject);
|
||||
reg.register_lint_pass(box ranges::StepByZero as LintPassObject);
|
||||
reg.register_lint_pass(box types::CastPass as LintPassObject);
|
||||
reg.register_lint_pass(box types::TypeComplexityPass as LintPassObject);
|
||||
reg.register_lint_pass(box matches::MatchPass as LintPassObject);
|
||||
reg.register_lint_pass(box misc::PatternPass as LintPassObject);
|
||||
reg.register_lint_pass(box minmax::MinMaxPass as LintPassObject);
|
||||
reg.register_late_lint_pass(box types::TypePass);
|
||||
reg.register_late_lint_pass(box misc::TopLevelRefPass);
|
||||
reg.register_late_lint_pass(box misc::CmpNan);
|
||||
reg.register_late_lint_pass(box eq_op::EqOp);
|
||||
reg.register_late_lint_pass(box bit_mask::BitMask);
|
||||
reg.register_late_lint_pass(box ptr_arg::PtrArg);
|
||||
reg.register_late_lint_pass(box needless_bool::NeedlessBool);
|
||||
reg.register_late_lint_pass(box approx_const::ApproxConstant);
|
||||
reg.register_late_lint_pass(box misc::FloatCmp);
|
||||
reg.register_early_lint_pass(box precedence::Precedence);
|
||||
reg.register_late_lint_pass(box eta_reduction::EtaPass);
|
||||
reg.register_late_lint_pass(box identity_op::IdentityOp);
|
||||
reg.register_late_lint_pass(box mut_mut::MutMut);
|
||||
reg.register_late_lint_pass(box len_zero::LenZero);
|
||||
reg.register_late_lint_pass(box misc::CmpOwned);
|
||||
reg.register_late_lint_pass(box attrs::AttrPass);
|
||||
reg.register_late_lint_pass(box collapsible_if::CollapsibleIf);
|
||||
reg.register_late_lint_pass(box misc::ModuloOne);
|
||||
reg.register_late_lint_pass(box unicode::Unicode);
|
||||
reg.register_late_lint_pass(box strings::StringAdd);
|
||||
reg.register_late_lint_pass(box returns::ReturnPass);
|
||||
reg.register_late_lint_pass(box methods::MethodsPass);
|
||||
reg.register_late_lint_pass(box shadow::ShadowPass);
|
||||
reg.register_late_lint_pass(box types::LetPass);
|
||||
reg.register_late_lint_pass(box types::UnitCmp);
|
||||
reg.register_late_lint_pass(box loops::LoopsPass);
|
||||
reg.register_late_lint_pass(box lifetimes::LifetimePass);
|
||||
reg.register_late_lint_pass(box ranges::StepByZero);
|
||||
reg.register_late_lint_pass(box types::CastPass);
|
||||
reg.register_late_lint_pass(box types::TypeComplexityPass);
|
||||
reg.register_late_lint_pass(box matches::MatchPass);
|
||||
reg.register_late_lint_pass(box misc::PatternPass);
|
||||
reg.register_late_lint_pass(box minmax::MinMaxPass);
|
||||
|
||||
reg.register_lint_group("clippy_pedantic", vec![
|
||||
methods::OPTION_UNWRAP_USED,
|
||||
|
@ -18,21 +18,23 @@ impl LintPass for LifetimePass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(NEEDLESS_LIFETIMES)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
impl LateLintPass for LifetimePass {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
if let ItemFn(ref decl, _, _, _, ref generics, _) = item.node {
|
||||
check_fn_inner(cx, decl, None, &generics, item.span);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &Context, item: &ImplItem) {
|
||||
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
|
||||
if let MethodImplItem(ref sig, _) = item.node {
|
||||
check_fn_inner(cx, &sig.decl, Some(&sig.explicit_self),
|
||||
&sig.generics, item.span);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &Context, item: &TraitItem) {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
|
||||
if let MethodTraitItem(ref sig, _) = item.node {
|
||||
check_fn_inner(cx, &sig.decl, Some(&sig.explicit_self),
|
||||
&sig.generics, item.span);
|
||||
@ -49,7 +51,7 @@ enum RefLt {
|
||||
}
|
||||
use self::RefLt::*;
|
||||
|
||||
fn check_fn_inner(cx: &Context, decl: &FnDecl, slf: Option<&ExplicitSelf>,
|
||||
fn check_fn_inner(cx: &LateContext, decl: &FnDecl, slf: Option<&ExplicitSelf>,
|
||||
generics: &Generics, span: Span) {
|
||||
if in_external_macro(cx, span) || has_where_lifetimes(&generics.where_clause) {
|
||||
return;
|
||||
|
16
src/loops.rs
16
src/loops.rs
@ -43,8 +43,10 @@ impl LintPass for LoopsPass {
|
||||
lint_array!(NEEDLESS_RANGE_LOOP, EXPLICIT_ITER_LOOP, ITER_NEXT_LOOP,
|
||||
WHILE_LET_LOOP, UNUSED_COLLECT, REVERSE_RANGE_LOOP, EXPLICIT_COUNTER_LOOP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for LoopsPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let Some((pat, arg, body)) = recover_for_loop(expr) {
|
||||
// check for looping over a range and then indexing a sequence with it
|
||||
// -> the iteratee must be a range literal
|
||||
@ -186,7 +188,7 @@ impl LintPass for LoopsPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &Context, stmt: &Stmt) {
|
||||
fn check_stmt(&mut self, cx: &LateContext, stmt: &Stmt) {
|
||||
if let StmtSemi(ref expr, _) = stmt.node {
|
||||
if let ExprMethodCall(ref method, _, ref args) = expr.node {
|
||||
if args.len() == 1 && method.node.name == "collect" &&
|
||||
@ -225,7 +227,7 @@ fn recover_for_loop(expr: &Expr) -> Option<(&Pat, &Expr, &Expr)> {
|
||||
}
|
||||
|
||||
struct VarVisitor<'v, 't: 'v> {
|
||||
cx: &'v Context<'v, 't>, // context reference
|
||||
cx: &'v LateContext<'v, 't>, // context reference
|
||||
var: Name, // var name to look for as index
|
||||
indexed: HashSet<Name>, // indexed variables
|
||||
nonindex: bool, // has the var been used otherwise?
|
||||
@ -258,7 +260,7 @@ impl<'v, 't> Visitor<'v> for VarVisitor<'v, 't> {
|
||||
|
||||
/// Return true if the type of expr is one that provides IntoIterator impls
|
||||
/// for &T and &mut T, such as Vec.
|
||||
fn is_ref_iterable_type(cx: &Context, e: &Expr) -> bool {
|
||||
fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
|
||||
// no walk_ptrs_ty: calling iter() on a reference can make sense because it
|
||||
// will allow further borrows afterwards
|
||||
let ty = cx.tcx.expr_ty(e);
|
||||
@ -320,7 +322,7 @@ enum VarState {
|
||||
|
||||
// Scan a for loop for variables that are incremented exactly once.
|
||||
struct IncrementVisitor<'v, 't: 'v> {
|
||||
cx: &'v Context<'v, 't>, // context reference
|
||||
cx: &'v LateContext<'v, 't>, // context reference
|
||||
states: HashMap<NodeId, VarState>, // incremented variables
|
||||
depth: u32, // depth of conditional expressions
|
||||
done: bool
|
||||
@ -376,7 +378,7 @@ impl<'v, 't> Visitor<'v> for IncrementVisitor<'v, 't> {
|
||||
|
||||
// Check whether a variable is initialized to zero at the start of a loop.
|
||||
struct InitializeVisitor<'v, 't: 'v> {
|
||||
cx: &'v Context<'v, 't>, // context reference
|
||||
cx: &'v LateContext<'v, 't>, // context reference
|
||||
end_expr: &'v Expr, // the for loop. Stop scanning here.
|
||||
var_id: NodeId,
|
||||
state: VarState,
|
||||
@ -454,7 +456,7 @@ impl<'v, 't> Visitor<'v> for InitializeVisitor<'v, 't> {
|
||||
}
|
||||
}
|
||||
|
||||
fn var_def_id(cx: &Context, expr: &Expr) -> Option<NodeId> {
|
||||
fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
|
||||
if let Some(path_res) = cx.tcx.def_map.borrow().get(&expr.id) {
|
||||
if let DefLocal(node_id) = path_res.base_def {
|
||||
return Some(node_id)
|
||||
|
@ -17,8 +17,10 @@ impl LintPass for MatchPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(SINGLE_MATCH, MATCH_REF_PATS)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for MatchPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprMatch(ref ex, ref arms, MatchSource::Normal) = expr.node {
|
||||
// check preconditions for SINGLE_MATCH
|
||||
// only two arms
|
||||
|
@ -36,8 +36,10 @@ impl LintPass for MethodsPass {
|
||||
lint_array!(OPTION_UNWRAP_USED, RESULT_UNWRAP_USED, STR_TO_STRING, STRING_TO_STRING,
|
||||
SHOULD_IMPLEMENT_TRAIT, WRONG_SELF_CONVENTION)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for MethodsPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprMethodCall(ref ident, _, ref args) = expr.node {
|
||||
let (obj_ty, ptr_depth) = walk_ptrs_ty_depth(cx.tcx.expr_ty(&args[0]));
|
||||
if ident.node.name == "unwrap" {
|
||||
@ -71,7 +73,7 @@ impl LintPass for MethodsPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
if let ItemImpl(_, _, _, None, ref ty, ref items) = item.node {
|
||||
for implitem in items {
|
||||
let name = implitem.ident.name;
|
||||
@ -229,7 +231,7 @@ fn is_bool(ty: &Ty) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_copy(cx: &Context, ast_ty: &Ty, item: &Item) -> bool {
|
||||
fn is_copy(cx: &LateContext, ast_ty: &Ty, item: &Item) -> bool {
|
||||
match cx.tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
|
||||
None => false,
|
||||
Some(ty) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc::lint::{Context, LintPass, LintArray};
|
||||
use rustc::lint::*;
|
||||
use rustc_front::hir::*;
|
||||
use syntax::ptr::P;
|
||||
use std::cmp::PartialOrd;
|
||||
@ -19,8 +19,10 @@ impl LintPass for MinMaxPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MIN_MAX)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for MinMaxPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let Some((outer_max, outer_c, oe)) = min_max(expr) {
|
||||
if let Some((inner_max, inner_c, _)) = min_max(oe) {
|
||||
if outer_max == inner_max { return; }
|
||||
|
32
src/misc.rs
32
src/misc.rs
@ -21,8 +21,10 @@ impl LintPass for TopLevelRefPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(TOPLEVEL_REF_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(&mut self, cx: &Context, k: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
|
||||
impl LateLintPass for TopLevelRefPass {
|
||||
fn check_fn(&mut self, cx: &LateContext, k: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
|
||||
if let FnKind::Closure = k {
|
||||
// Does not apply to closures
|
||||
return
|
||||
@ -49,8 +51,10 @@ impl LintPass for CmpNan {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(CMP_NAN)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for CmpNan {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprBinary(ref cmp, ref left, ref right) = expr.node {
|
||||
if is_comparison_binop(cmp.node) {
|
||||
if let &ExprPath(_, ref path) = &left.node {
|
||||
@ -64,7 +68,7 @@ impl LintPass for CmpNan {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_nan(cx: &Context, path: &Path, span: Span) {
|
||||
fn check_nan(cx: &LateContext, path: &Path, span: Span) {
|
||||
path.segments.last().map(|seg| if seg.identifier.name == "NAN" {
|
||||
span_lint(cx, CMP_NAN, span,
|
||||
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead");
|
||||
@ -83,8 +87,10 @@ impl LintPass for FloatCmp {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(FLOAT_CMP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for FloatCmp {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprBinary(ref cmp, ref left, ref right) = expr.node {
|
||||
let op = cmp.node;
|
||||
if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) {
|
||||
@ -109,7 +115,7 @@ impl LintPass for FloatCmp {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_float(cx: &Context, expr: &Expr) -> bool {
|
||||
fn is_float(cx: &LateContext, expr: &Expr) -> bool {
|
||||
if let ty::TyFloat(_) = walk_ptrs_ty(cx.tcx.expr_ty(expr)).sty {
|
||||
true
|
||||
} else {
|
||||
@ -127,8 +133,10 @@ impl LintPass for CmpOwned {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(CMP_OWNED)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for CmpOwned {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprBinary(ref cmp, ref left, ref right) = expr.node {
|
||||
if is_comparison_binop(cmp.node) {
|
||||
check_to_owned(cx, left, right.span);
|
||||
@ -138,7 +146,7 @@ impl LintPass for CmpOwned {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) {
|
||||
fn check_to_owned(cx: &LateContext, expr: &Expr, other_span: Span) {
|
||||
match expr.node {
|
||||
ExprMethodCall(Spanned{node: ref ident, ..}, _, ref args) => {
|
||||
let name = ident.name;
|
||||
@ -165,7 +173,7 @@ fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_str_arg(cx: &Context, args: &[P<Expr>]) -> bool {
|
||||
fn is_str_arg(cx: &LateContext, args: &[P<Expr>]) -> bool {
|
||||
args.len() == 1 && if let ty::TyStr =
|
||||
walk_ptrs_ty(cx.tcx.expr_ty(&args[0])).sty { true } else { false }
|
||||
}
|
||||
@ -179,8 +187,10 @@ impl LintPass for ModuloOne {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MODULO_ONE)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for ModuloOne {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprBinary(ref cmp, _, ref right) = expr.node {
|
||||
if let &Spanned {node: BinOp_::BiRem, ..} = cmp {
|
||||
if is_integer_literal(right, 1) {
|
||||
@ -200,8 +210,10 @@ impl LintPass for PatternPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(REDUNDANT_PATTERN)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &Context, pat: &Pat) {
|
||||
impl LateLintPass for PatternPass {
|
||||
fn check_pat(&mut self, cx: &LateContext, pat: &Pat) {
|
||||
if let PatIdent(_, ref ident, Some(ref right)) = pat.node {
|
||||
if right.node == PatWild(PatWildSingle) {
|
||||
cx.span_lint(REDUNDANT_PATTERN, pat.span, &format!(
|
||||
|
@ -15,18 +15,20 @@ impl LintPass for MutMut {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MUT_MUT)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for MutMut {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
check_expr_mut(cx, expr)
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &Context, ty: &Ty) {
|
||||
fn check_ty(&mut self, cx: &LateContext, ty: &Ty) {
|
||||
unwrap_mut(ty).and_then(unwrap_mut).map_or((), |_| span_lint(cx, MUT_MUT,
|
||||
ty.span, "generally you want to avoid `&mut &mut _` if possible"))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_mut(cx: &Context, expr: &Expr) {
|
||||
fn check_expr_mut(cx: &LateContext, expr: &Expr) {
|
||||
if in_external_macro(cx, expr.span) { return; }
|
||||
|
||||
fn unwrap_addr(expr : &Expr) -> Option<&Expr> {
|
||||
|
@ -23,8 +23,10 @@ impl LintPass for NeedlessBool {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(NEEDLESS_BOOL)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for NeedlessBool {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let ExprIf(ref pred, ref then_block, Some(ref else_expr)) = e.node {
|
||||
match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
|
||||
(Some(true), Some(true)) => {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use rustc::lint::*;
|
||||
use rustc_front::hir::*;
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::ast::Lit_::*;
|
||||
use syntax::ast::*;
|
||||
use utils::span_lint;
|
||||
|
||||
declare_lint!(pub PRECEDENCE, Warn,
|
||||
@ -15,8 +14,10 @@ impl LintPass for Precedence {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(PRECEDENCE)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl EarlyLintPass for Precedence {
|
||||
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
|
||||
if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node {
|
||||
if is_bit_op(op) && (is_arith_expr(left) || is_arith_expr(right)) {
|
||||
span_lint(cx, PRECEDENCE, expr.span,
|
||||
|
@ -23,27 +23,29 @@ impl LintPass for PtrArg {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(PTR_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
impl LateLintPass for PtrArg {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
if let &ItemFn(ref decl, _, _, _, _, _) = &item.node {
|
||||
check_fn(cx, decl);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &Context, item: &ImplItem) {
|
||||
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
|
||||
if let &MethodImplItem(ref sig, _) = &item.node {
|
||||
check_fn(cx, &sig.decl);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &Context, item: &TraitItem) {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
|
||||
if let &MethodTraitItem(ref sig, _) = &item.node {
|
||||
check_fn(cx, &sig.decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(cx: &Context, decl: &FnDecl) {
|
||||
fn check_fn(cx: &LateContext, decl: &FnDecl) {
|
||||
for arg in &decl.inputs {
|
||||
if let Some(pat_ty) = cx.tcx.pat_ty_opt(&arg.pat) {
|
||||
if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = pat_ty.sty {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc::lint::{Context, LintArray, LintPass};
|
||||
use rustc::lint::*;
|
||||
use rustc_front::hir::*;
|
||||
use syntax::codemap::Spanned;
|
||||
use utils::{match_type, is_integer_literal};
|
||||
@ -15,8 +15,10 @@ impl LintPass for StepByZero {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(RANGE_STEP_BY_ZERO)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for StepByZero {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprMethodCall(Spanned { node: ref ident, .. }, _,
|
||||
ref args) = expr.node {
|
||||
// Only warn on literal ranges.
|
||||
@ -30,7 +32,7 @@ impl LintPass for StepByZero {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_range(cx: &Context, expr: &Expr) -> bool {
|
||||
fn is_range(cx: &LateContext, expr: &Expr) -> bool {
|
||||
// No need for walk_ptrs_ty here because step_by moves self, so it
|
||||
// can't be called on a borrowed range.
|
||||
let ty = cx.tcx.expr_ty(expr);
|
||||
|
@ -17,7 +17,7 @@ pub struct ReturnPass;
|
||||
|
||||
impl ReturnPass {
|
||||
// Check the final stmt or expr in a block for unnecessary return.
|
||||
fn check_block_return(&mut self, cx: &Context, block: &Block) {
|
||||
fn check_block_return(&mut self, cx: &LateContext, block: &Block) {
|
||||
if let Some(ref expr) = block.expr {
|
||||
self.check_final_expr(cx, expr);
|
||||
} else if let Some(stmt) = block.stmts.last() {
|
||||
@ -30,7 +30,7 @@ impl ReturnPass {
|
||||
}
|
||||
|
||||
// Check a the final expression in a block if it's a return.
|
||||
fn check_final_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
fn check_final_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
match expr.node {
|
||||
// simple return is always "bad"
|
||||
ExprRet(Some(ref inner)) => {
|
||||
@ -57,7 +57,7 @@ impl ReturnPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_return_lint(&mut self, cx: &Context, spans: (Span, Span)) {
|
||||
fn emit_return_lint(&mut self, cx: &LateContext, spans: (Span, Span)) {
|
||||
if in_external_macro(cx, spans.1) {return;}
|
||||
span_lint(cx, NEEDLESS_RETURN, spans.0, &format!(
|
||||
"unneeded return statement. Consider using `{}` \
|
||||
@ -66,7 +66,7 @@ impl ReturnPass {
|
||||
}
|
||||
|
||||
// Check for "let x = EXPR; x"
|
||||
fn check_let_return(&mut self, cx: &Context, block: &Block) {
|
||||
fn check_let_return(&mut self, cx: &LateContext, block: &Block) {
|
||||
// we need both a let-binding stmt and an expr
|
||||
if_let_chain! {
|
||||
[
|
||||
@ -84,7 +84,7 @@ impl ReturnPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_let_lint(&mut self, cx: &Context, lint_span: Span, note_span: Span) {
|
||||
fn emit_let_lint(&mut self, cx: &LateContext, lint_span: Span, note_span: Span) {
|
||||
if in_external_macro(cx, note_span) {return;}
|
||||
span_lint(cx, LET_AND_RETURN, lint_span,
|
||||
"returning the result of a let binding. \
|
||||
@ -100,8 +100,10 @@ impl LintPass for ReturnPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(NEEDLESS_RETURN, LET_AND_RETURN)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(&mut self, cx: &Context, _: FnKind, _: &FnDecl,
|
||||
impl LateLintPass for ReturnPass {
|
||||
fn check_fn(&mut self, cx: &LateContext, _: FnKind, _: &FnDecl,
|
||||
block: &Block, _: Span, _: NodeId) {
|
||||
self.check_block_return(cx, block);
|
||||
self.check_let_return(cx, block);
|
||||
|
@ -4,7 +4,7 @@ use reexport::*;
|
||||
use syntax::codemap::Span;
|
||||
use rustc_front::visit::FnKind;
|
||||
|
||||
use rustc::lint::{Context, Level, Lint, LintArray, LintPass};
|
||||
use rustc::lint::*;
|
||||
use rustc::middle::def::Def::{DefVariant, DefStruct};
|
||||
|
||||
use utils::{in_external_macro, snippet, span_lint, span_note_and_lint};
|
||||
@ -25,14 +25,17 @@ impl LintPass for ShadowPass {
|
||||
lint_array!(SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED)
|
||||
}
|
||||
|
||||
fn check_fn(&mut self, cx: &Context, _: FnKind, decl: &FnDecl,
|
||||
}
|
||||
|
||||
impl LateLintPass for ShadowPass {
|
||||
fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl,
|
||||
block: &Block, _: Span, _: NodeId) {
|
||||
if in_external_macro(cx, block.span) { return; }
|
||||
check_fn(cx, decl, block);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(cx: &Context, decl: &FnDecl, block: &Block) {
|
||||
fn check_fn(cx: &LateContext, decl: &FnDecl, block: &Block) {
|
||||
let mut bindings = Vec::new();
|
||||
for arg in &decl.inputs {
|
||||
if let PatIdent(_, ident, _) = arg.pat.node {
|
||||
@ -42,7 +45,7 @@ fn check_fn(cx: &Context, decl: &FnDecl, block: &Block) {
|
||||
check_block(cx, block, &mut bindings);
|
||||
}
|
||||
|
||||
fn check_block(cx: &Context, block: &Block, bindings: &mut Vec<(Name, Span)>) {
|
||||
fn check_block(cx: &LateContext, block: &Block, bindings: &mut Vec<(Name, Span)>) {
|
||||
let len = bindings.len();
|
||||
for stmt in &block.stmts {
|
||||
match stmt.node {
|
||||
@ -55,7 +58,7 @@ fn check_block(cx: &Context, block: &Block, bindings: &mut Vec<(Name, Span)>) {
|
||||
bindings.truncate(len);
|
||||
}
|
||||
|
||||
fn check_decl(cx: &Context, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
|
||||
fn check_decl(cx: &LateContext, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
|
||||
if in_external_macro(cx, decl.span) { return; }
|
||||
if let DeclLocal(ref local) = decl.node {
|
||||
let Local{ ref pat, ref ty, ref init, id: _, span } = **local;
|
||||
@ -69,14 +72,14 @@ fn check_decl(cx: &Context, decl: &Decl, bindings: &mut Vec<(Name, Span)>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_binding(cx: &Context, pat: &Pat) -> bool {
|
||||
fn is_binding(cx: &LateContext, pat: &Pat) -> bool {
|
||||
match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
|
||||
Some(DefVariant(..)) | Some(DefStruct(..)) => false,
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
||||
fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
|
||||
fn check_pat(cx: &LateContext, pat: &Pat, init: &Option<&Expr>, span: Span,
|
||||
bindings: &mut Vec<(Name, Span)>) {
|
||||
//TODO: match more stuff / destructuring
|
||||
match pat.node {
|
||||
@ -153,9 +156,9 @@ fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
|
||||
}
|
||||
}
|
||||
|
||||
fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
|
||||
fn lint_shadow<T>(cx: &LateContext, name: Name, span: Span, lspan: Span, init:
|
||||
&Option<T>, prev_span: Span) where T: Deref<Target=Expr> {
|
||||
fn note_orig(cx: &Context, lint: &'static Lint, span: Span) {
|
||||
fn note_orig(cx: &LateContext, lint: &'static Lint, span: Span) {
|
||||
if cx.current_level(lint) != Level::Allow {
|
||||
cx.sess().span_note(span, "previous binding is here");
|
||||
}
|
||||
@ -191,10 +194,10 @@ fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(cx: &Context, expr: &Expr, bindings: &mut Vec<(Name, Span)>) {
|
||||
fn check_expr(cx: &LateContext, expr: &Expr, bindings: &mut Vec<(Name, Span)>) {
|
||||
if in_external_macro(cx, expr.span) { return; }
|
||||
match expr.node {
|
||||
ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
|
||||
ExprUnary(_, ref e) | ExprField(ref e, _) |
|
||||
ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(None, ref e)
|
||||
=> { check_expr(cx, e, bindings) },
|
||||
ExprBox(Some(ref place), ref e) => {
|
||||
@ -233,7 +236,7 @@ fn check_expr(cx: &Context, expr: &Expr, bindings: &mut Vec<(Name, Span)>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ty(cx: &Context, ty: &Ty, bindings: &mut Vec<(Name, Span)>) {
|
||||
fn check_ty(cx: &LateContext, ty: &Ty, bindings: &mut Vec<(Name, Span)>) {
|
||||
match ty.node {
|
||||
TyParen(ref sty) | TyObjectSum(ref sty, _) |
|
||||
TyVec(ref sty) => check_ty(cx, sty, bindings),
|
||||
@ -252,7 +255,6 @@ fn check_ty(cx: &Context, ty: &Ty, bindings: &mut Vec<(Name, Span)>) {
|
||||
fn is_self_shadow(name: Name, expr: &Expr) -> bool {
|
||||
match expr.node {
|
||||
ExprBox(_, ref inner) |
|
||||
ExprParen(ref inner) |
|
||||
ExprAddrOf(_, ref inner) => is_self_shadow(name, inner),
|
||||
ExprBlock(ref block) => block.stmts.is_empty() && block.expr.as_ref().
|
||||
map_or(false, |ref e| is_self_shadow(name, e)),
|
||||
@ -275,7 +277,7 @@ fn contains_self(name: Name, expr: &Expr) -> bool {
|
||||
// no subexprs
|
||||
ExprLit(_) => false,
|
||||
// one subexpr
|
||||
ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
|
||||
ExprUnary(_, ref e) | ExprField(ref e, _) |
|
||||
ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(_, ref e) |
|
||||
ExprCast(ref e, _) =>
|
||||
contains_self(name, e),
|
||||
|
@ -30,8 +30,10 @@ impl LintPass for StringAdd {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(STRING_ADD, STRING_ADD_ASSIGN)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &Expr) {
|
||||
impl LateLintPass for StringAdd {
|
||||
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
|
||||
if let &ExprBinary(Spanned{ node: BiAdd, .. }, ref left, _) = &e.node {
|
||||
if is_string(cx, left) {
|
||||
if let Allow = cx.current_level(STRING_ADD_ASSIGN) {
|
||||
@ -59,18 +61,17 @@ impl LintPass for StringAdd {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_string(cx: &Context, e: &Expr) -> bool {
|
||||
fn is_string(cx: &LateContext, e: &Expr) -> bool {
|
||||
match_type(cx, walk_ptrs_ty(cx.tcx.expr_ty(e)), &STRING_PATH)
|
||||
}
|
||||
|
||||
fn is_add(cx: &Context, src: &Expr, target: &Expr) -> bool {
|
||||
fn is_add(cx: &LateContext, src: &Expr, target: &Expr) -> bool {
|
||||
match src.node {
|
||||
ExprBinary(Spanned{ node: BiAdd, .. }, ref left, _) =>
|
||||
is_exp_equal(cx, target, left),
|
||||
ExprBlock(ref block) => block.stmts.is_empty() &&
|
||||
block.expr.as_ref().map_or(false,
|
||||
|expr| is_add(cx, expr, target)),
|
||||
ExprParen(ref expr) => is_add(cx, expr, target),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
42
src/types.rs
42
src/types.rs
@ -26,8 +26,10 @@ impl LintPass for TypePass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(BOX_VEC, LINKEDLIST)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &Context, ast_ty: &Ty) {
|
||||
impl LateLintPass for TypePass {
|
||||
fn check_ty(&mut self, cx: &LateContext, ast_ty: &Ty) {
|
||||
if let Some(ty) = cx.tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
|
||||
if let ty::TyBox(ref inner) = ty.sty {
|
||||
if match_type(cx, inner, &VEC_PATH) {
|
||||
@ -53,7 +55,7 @@ pub struct LetPass;
|
||||
declare_lint!(pub LET_UNIT_VALUE, Warn,
|
||||
"creating a let binding to a value of unit type, which usually can't be used afterwards");
|
||||
|
||||
fn check_let_unit(cx: &Context, decl: &Decl) {
|
||||
fn check_let_unit(cx: &LateContext, decl: &Decl) {
|
||||
if let DeclLocal(ref local) = decl.node {
|
||||
let bindtype = &cx.tcx.pat_ty(&local.pat).sty;
|
||||
if *bindtype == ty::TyTuple(vec![]) {
|
||||
@ -70,8 +72,10 @@ impl LintPass for LetPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(LET_UNIT_VALUE)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_decl(&mut self, cx: &Context, decl: &Decl) {
|
||||
impl LateLintPass for LetPass {
|
||||
fn check_decl(&mut self, cx: &LateContext, decl: &Decl) {
|
||||
check_let_unit(cx, decl)
|
||||
}
|
||||
}
|
||||
@ -86,8 +90,10 @@ impl LintPass for UnitCmp {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(UNIT_CMP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for UnitCmp {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if in_macro(cx, expr.span) { return; }
|
||||
if let ExprBinary(ref cmp, ref left, _) = expr.node {
|
||||
let op = cmp.node;
|
||||
@ -135,7 +141,7 @@ fn is_isize_or_usize(typ: &ty::TyS) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn span_precision_loss_lint(cx: &Context, expr: &Expr, cast_from: &ty::TyS, cast_to_f64: bool) {
|
||||
fn span_precision_loss_lint(cx: &LateContext, expr: &Expr, cast_from: &ty::TyS, cast_to_f64: bool) {
|
||||
let mantissa_nbits = if cast_to_f64 {52} else {23};
|
||||
let arch_dependent = is_isize_or_usize(cast_from) && cast_to_f64;
|
||||
let arch_dependent_str = "on targets with 64-bit wide pointers ";
|
||||
@ -154,7 +160,7 @@ enum ArchSuffix {
|
||||
_32, _64, None
|
||||
}
|
||||
|
||||
fn check_truncation_and_wrapping(cx: &Context, expr: &Expr, cast_from: &ty::TyS, cast_to: &ty::TyS) {
|
||||
fn check_truncation_and_wrapping(cx: &LateContext, expr: &Expr, cast_from: &ty::TyS, cast_to: &ty::TyS) {
|
||||
let arch_64_suffix = " on targets with 64-bit wide pointers";
|
||||
let arch_32_suffix = " on targets with 32-bit wide pointers";
|
||||
let cast_unsigned_to_signed = !cast_from.is_signed() && cast_to.is_signed();
|
||||
@ -207,8 +213,10 @@ impl LintPass for CastPass {
|
||||
CAST_POSSIBLE_TRUNCATION,
|
||||
CAST_POSSIBLE_WRAP)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for CastPass {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprCast(ref ex, _) = expr.node {
|
||||
let (cast_from, cast_to) = (cx.tcx.expr_ty(ex), cx.tcx.expr_ty(expr));
|
||||
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx, expr.span) {
|
||||
@ -262,16 +270,18 @@ impl LintPass for TypeComplexityPass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(TYPE_COMPLEXITY)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(&mut self, cx: &Context, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
|
||||
impl LateLintPass for TypeComplexityPass {
|
||||
fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Block, _: Span, _: NodeId) {
|
||||
check_fndecl(cx, decl);
|
||||
}
|
||||
|
||||
fn check_struct_field(&mut self, cx: &Context, field: &StructField) {
|
||||
fn check_struct_field(&mut self, cx: &LateContext, field: &StructField) {
|
||||
check_type(cx, &field.node.ty);
|
||||
}
|
||||
|
||||
fn check_variant(&mut self, cx: &Context, var: &Variant, _: &Generics) {
|
||||
fn check_variant(&mut self, cx: &LateContext, var: &Variant, _: &Generics) {
|
||||
// StructVariant is covered by check_struct_field
|
||||
if let TupleVariantKind(ref args) = var.node.kind {
|
||||
for arg in args {
|
||||
@ -280,7 +290,7 @@ impl LintPass for TypeComplexityPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &Item) {
|
||||
fn check_item(&mut self, cx: &LateContext, item: &Item) {
|
||||
match item.node {
|
||||
ItemStatic(ref ty, _, _) |
|
||||
ItemConst(ref ty, _) => check_type(cx, ty),
|
||||
@ -289,7 +299,7 @@ impl LintPass for TypeComplexityPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &Context, item: &TraitItem) {
|
||||
fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
|
||||
match item.node {
|
||||
ConstTraitItem(ref ty, _) |
|
||||
TypeTraitItem(_, Some(ref ty)) => check_type(cx, ty),
|
||||
@ -299,7 +309,7 @@ impl LintPass for TypeComplexityPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &Context, item: &ImplItem) {
|
||||
fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
|
||||
match item.node {
|
||||
ConstImplItem(ref ty, _) |
|
||||
TypeImplItem(ref ty) => check_type(cx, ty),
|
||||
@ -308,14 +318,14 @@ impl LintPass for TypeComplexityPass {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(&mut self, cx: &Context, local: &Local) {
|
||||
fn check_local(&mut self, cx: &LateContext, local: &Local) {
|
||||
if let Some(ref ty) = local.ty {
|
||||
check_type(cx, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fndecl(cx: &Context, decl: &FnDecl) {
|
||||
fn check_fndecl(cx: &LateContext, decl: &FnDecl) {
|
||||
for arg in &decl.inputs {
|
||||
check_type(cx, &arg.ty);
|
||||
}
|
||||
@ -324,7 +334,7 @@ fn check_fndecl(cx: &Context, decl: &FnDecl) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_type(cx: &Context, ty: &Ty) {
|
||||
fn check_type(cx: &LateContext, ty: &Ty) {
|
||||
if in_macro(cx, ty.span) { return; }
|
||||
let score = {
|
||||
let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 };
|
||||
|
@ -25,8 +25,10 @@ impl LintPass for Unicode {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(ZERO_WIDTH_SPACE, NON_ASCII_LITERAL, UNICODE_NOT_NFC)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
|
||||
impl LateLintPass for Unicode {
|
||||
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
|
||||
if let ExprLit(ref lit) = expr.node {
|
||||
if let LitStr(_, _) = lit.node {
|
||||
check_str(cx, lit.span)
|
||||
@ -47,7 +49,7 @@ fn escape<T: Iterator<Item=char>>(s: T) -> String {
|
||||
result
|
||||
}
|
||||
|
||||
fn check_str(cx: &Context, span: Span) {
|
||||
fn check_str(cx: &LateContext, span: Span) {
|
||||
let string = snippet(cx, span, "");
|
||||
if string.contains('\u{200B}') {
|
||||
span_help_and_lint(cx, ZERO_WIDTH_SPACE, span,
|
||||
|
30
src/utils.rs
30
src/utils.rs
@ -16,7 +16,7 @@ pub const VEC_PATH: [&'static str; 3] = ["collections", "vec", "Vec"];
|
||||
pub const LL_PATH: [&'static str; 3] = ["collections", "linked_list", "LinkedList"];
|
||||
|
||||
/// returns true this expn_info was expanded by any macro
|
||||
pub fn in_macro(cx: &Context, span: Span) -> bool {
|
||||
pub fn in_macro(cx: &LateContext, span: Span) -> bool {
|
||||
cx.sess().codemap().with_expn_info(span.expn_id,
|
||||
|info| info.map_or(false, |i| {
|
||||
match i.callee.format {
|
||||
@ -28,10 +28,10 @@ pub fn in_macro(cx: &Context, span: Span) -> bool {
|
||||
|
||||
/// returns true if the macro that expanded the crate was outside of
|
||||
/// the current crate or was a compiler plugin
|
||||
pub fn in_external_macro(cx: &Context, span: Span) -> bool {
|
||||
pub fn in_external_macro<T: LintContext>(cx: &T, span: Span) -> bool {
|
||||
/// invokes in_macro with the expansion info of the given span
|
||||
/// slightly heavy, try to use this after other checks have already happened
|
||||
fn in_macro_ext(cx: &Context, opt_info: Option<&ExpnInfo>) -> bool {
|
||||
fn in_macro_ext<T: LintContext>(cx: &T, opt_info: Option<&ExpnInfo>) -> bool {
|
||||
// no ExpnInfo = no macro
|
||||
opt_info.map_or(false, |info| {
|
||||
match info.callee.format {
|
||||
@ -65,12 +65,12 @@ pub fn in_external_macro(cx: &Context, span: Span) -> bool {
|
||||
/// check if a DefId's path matches the given absolute type path
|
||||
/// usage e.g. with
|
||||
/// `match_def_path(cx, id, &["core", "option", "Option"])`
|
||||
pub fn match_def_path(cx: &Context, def_id: DefId, path: &[&str]) -> bool {
|
||||
pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
|
||||
cx.tcx.with_path(def_id, |iter| iter.zip(path).all(|(nm, p)| nm.name() == p))
|
||||
}
|
||||
|
||||
/// check if type is struct or enum type with given def path
|
||||
pub fn match_type(cx: &Context, ty: ty::Ty, path: &[&str]) -> bool {
|
||||
pub fn match_type(cx: &LateContext, ty: ty::Ty, path: &[&str]) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyEnum(ref adt, _) | ty::TyStruct(ref adt, _) => {
|
||||
match_def_path(cx, adt.did, path)
|
||||
@ -82,7 +82,7 @@ pub fn match_type(cx: &Context, ty: ty::Ty, path: &[&str]) -> bool {
|
||||
}
|
||||
|
||||
/// check if method call given in "expr" belongs to given trait
|
||||
pub fn match_trait_method(cx: &Context, expr: &Expr, path: &[&str]) -> bool {
|
||||
pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool {
|
||||
let method_call = ty::MethodCall::expr(expr.id);
|
||||
let trt_id = cx.tcx.tables
|
||||
.borrow().method_map.get(&method_call)
|
||||
@ -102,7 +102,7 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool {
|
||||
}
|
||||
|
||||
/// get the name of the item the expression is in, if available
|
||||
pub fn get_item_name(cx: &Context, expr: &Expr) -> Option<Name> {
|
||||
pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> {
|
||||
let parent_id = cx.tcx.map.get_parent(expr.id);
|
||||
match cx.tcx.map.find(parent_id) {
|
||||
Some(NodeItem(&Item{ ref ident, .. })) |
|
||||
@ -116,7 +116,7 @@ pub fn get_item_name(cx: &Context, expr: &Expr) -> Option<Name> {
|
||||
|
||||
/// convert a span to a code snippet if available, otherwise use default, e.g.
|
||||
/// `snippet(cx, expr.span, "..")`
|
||||
pub fn snippet<'a>(cx: &Context, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
pub fn snippet<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
cx.sess().codemap().span_to_snippet(span).map(From::from).unwrap_or(Cow::Borrowed(default))
|
||||
}
|
||||
|
||||
@ -124,13 +124,13 @@ pub fn snippet<'a>(cx: &Context, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
/// `snippet(cx, expr.span, "..")`
|
||||
/// This trims the code of indentation, except for the first line
|
||||
/// Use it for blocks or block-like things which need to be printed as such
|
||||
pub fn snippet_block<'a>(cx: &Context, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
pub fn snippet_block<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
|
||||
let snip = snippet(cx, span, default);
|
||||
trim_multiline(snip, true)
|
||||
}
|
||||
|
||||
/// Like snippet_block, but add braces if the expr is not an ExprBlock
|
||||
pub fn expr_block<'a>(cx: &Context, expr: &Expr, default: &'a str) -> Cow<'a, str> {
|
||||
pub fn expr_block<'a, T: LintContext>(cx: &T, expr: &Expr, default: &'a str) -> Cow<'a, str> {
|
||||
let code = snippet_block(cx, expr.span, default);
|
||||
if let ExprBlock(_) = expr.node {
|
||||
code
|
||||
@ -169,7 +169,7 @@ fn trim_multiline_inner(s: Cow<str>, ignore_first: bool, ch: char) -> Cow<str> {
|
||||
}
|
||||
|
||||
/// get a parent expr if any – this is useful to constrain a lint
|
||||
pub fn get_parent_expr<'c>(cx: &'c Context, e: &Expr) -> Option<&'c Expr> {
|
||||
pub fn get_parent_expr<'c>(cx: &'c LateContext, e: &Expr) -> Option<&'c Expr> {
|
||||
let map = &cx.tcx.map;
|
||||
let node_id : NodeId = e.id;
|
||||
let parent_id : NodeId = map.get_parent_node(node_id);
|
||||
@ -179,7 +179,7 @@ pub fn get_parent_expr<'c>(cx: &'c Context, e: &Expr) -> Option<&'c Expr> {
|
||||
}
|
||||
|
||||
#[cfg(not(feature="structured_logging"))]
|
||||
pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
cx.span_lint(lint, sp, msg);
|
||||
if cx.current_level(lint) != Level::Allow {
|
||||
cx.sess().fileline_help(sp, &format!("for further information visit \
|
||||
@ -189,7 +189,7 @@ pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
}
|
||||
|
||||
#[cfg(feature="structured_logging")]
|
||||
pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
// lint.name / lint.desc is can give details of the lint
|
||||
// cx.sess().codemap() has all these nice functions for line/column/snippet details
|
||||
// http://doc.rust-lang.org/syntax/codemap/struct.CodeMap.html#method.span_to_string
|
||||
@ -201,7 +201,7 @@ pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
|
||||
pub fn span_help_and_lint<T: LintContext>(cx: &T, lint: &'static Lint, span: Span,
|
||||
msg: &str, help: &str) {
|
||||
cx.span_lint(lint, span, msg);
|
||||
if cx.current_level(lint) != Level::Allow {
|
||||
@ -211,7 +211,7 @@ pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span_note_and_lint(cx: &Context, lint: &'static Lint, span: Span,
|
||||
pub fn span_note_and_lint<T: LintContext>(cx: &T, lint: &'static Lint, span: Span,
|
||||
msg: &str, note_span: Span, note: &str) {
|
||||
cx.span_lint(lint, span, msg);
|
||||
if cx.current_level(lint) != Level::Allow {
|
||||
|
@ -12,7 +12,7 @@ fn main() {
|
||||
let mut x = 1;
|
||||
let x = &mut x; //~ERROR: x is shadowed by itself in &mut x
|
||||
let x = { x }; //~ERROR: x is shadowed by itself in { x }
|
||||
let x = (&*x); //~ERROR: x is shadowed by itself in (&*x)
|
||||
let x = (&*x); //~ERROR: x is shadowed by itself in &*x
|
||||
let x = { *x + 1 }; //~ERROR: x is shadowed by { *x + 1 } which reuses
|
||||
let x = id(x); //~ERROR: x is shadowed by id(x) which reuses
|
||||
let x = (1, x); //~ERROR: x is shadowed by (1, x) which reuses
|
||||
|
Loading…
Reference in New Issue
Block a user