This commit is contained in:
Oliver Schneider 2017-08-11 14:11:46 +02:00 committed by Oliver Schneider
parent 0e4c49b145
commit 459cf467c5
10 changed files with 52 additions and 48 deletions

View file

@ -8,7 +8,7 @@ use rustc::hir::intravisit::{Visitor, walk_expr, NestedVisitorMap};
use syntax::ast::{Attribute, NodeId};
use syntax::codemap::Span;
use utils::{in_macro, LimitStack, span_help_and_lint, paths, match_type};
use utils::{in_macro, LimitStack, span_help_and_lint, paths, match_type, is_allowed};
/// **What it does:** Checks for methods with high cyclomatic complexity.
///
@ -79,7 +79,16 @@ impl CyclomaticComplexity {
};
if cc + divergence < match_arms + short_circuits {
report_cc_bug(cx, cc, match_arms, divergence, short_circuits, ret_adjust, span);
report_cc_bug(
cx,
cc,
match_arms,
divergence,
short_circuits,
ret_adjust,
span,
body.id().node_id,
);
} else {
let mut rust_cc = cc + divergence - match_arms - short_circuits;
// prevent degenerate cases where unreachable code contains `return` statements
@ -180,7 +189,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
}
#[cfg(feature = "debugging")]
fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span) {
#[allow(too_many_arguments)]
fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, _: NodeId) {
span_bug!(
span,
"Clippy encountered a bug calculating cyclomatic complexity: cc = {}, arms = {}, \
@ -193,8 +203,9 @@ fn report_cc_bug(_: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, re
);
}
#[cfg(not(feature = "debugging"))]
fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span) {
if cx.current_level(CYCLOMATIC_COMPLEXITY) != Level::Allow {
#[allow(too_many_arguments)]
fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, id: NodeId) {
if !is_allowed(cx, CYCLOMATIC_COMPLEXITY, id) {
cx.sess().span_note_without_error(
span,
&format!(

View file

@ -12,7 +12,7 @@ use syntax::ast::NodeId;
use syntax::codemap::Span;
use utils::paths;
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};
expr_block, walk_ptrs_ty, is_expn_of, remove_blocks, is_allowed};
use utils::sugg::Sugg;
/// **What it does:** Checks for matches with a single arm where an `if let`
@ -194,7 +194,7 @@ fn check_single_match(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
return;
};
let ty = cx.tables.expr_ty(ex);
if ty.sty != ty::TyBool || cx.current_level(MATCH_BOOL) == Allow {
if ty.sty != ty::TyBool || is_allowed(cx, MATCH_BOOL, ex.id) {
check_single_match_single_pattern(cx, ex, arms, expr, els);
check_single_match_opt_like(cx, ex, arms, expr, ty, els);
}

View file

@ -22,6 +22,7 @@
//
//
//
//
// rs#L246
//

View file

@ -104,7 +104,9 @@ fn get_whitelist(interned_name: &str) -> Option<&'static [&'static str]> {
}
fn whitelisted(interned_name: &str, list: &[&str]) -> bool {
list.iter().any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name))
list.iter().any(|&name| {
interned_name.starts_with(name) || interned_name.ends_with(name)
})
}
impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {

View file

@ -2,7 +2,7 @@ use rustc::hir::*;
use rustc::lint::*;
use syntax::codemap::Spanned;
use utils::SpanlessEq;
use utils::{match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty, get_parent_expr};
use utils::{match_type, paths, span_lint, span_lint_and_sugg, walk_ptrs_ty, get_parent_expr, is_allowed};
/// **What it does:** Checks for string appends of the form `x = x + y` (without
/// `let`!).
@ -83,9 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx 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) {
// the string_add_assign is allow, so no duplicates
} else {
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
let parent = get_parent_expr(cx, e);
if let Some(p) = parent {
if let ExprAssign(ref target, _) = p.node {

View file

@ -1,9 +1,9 @@
use rustc::lint::*;
use rustc::hir::*;
use syntax::ast::LitKind;
use syntax::ast::{LitKind, NodeId};
use syntax::codemap::Span;
use unicode_normalization::UnicodeNormalization;
use utils::{snippet, span_help_and_lint};
use utils::{snippet, span_help_and_lint, is_allowed};
/// **What it does:** Checks for the Unicode zero-width space in the code.
///
@ -73,7 +73,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Unicode {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if let ExprLit(ref lit) = expr.node {
if let LitKind::Str(_, _) = lit.node {
check_str(cx, lit.span)
check_str(cx, lit.span, expr.id)
}
}
}
@ -93,7 +93,7 @@ fn escape<T: Iterator<Item = char>>(s: T) -> String {
result
}
fn check_str(cx: &LateContext, span: Span) {
fn check_str(cx: &LateContext, span: Span, id: NodeId) {
let string = snippet(cx, span, "");
if string.contains('\u{200B}') {
span_help_and_lint(
@ -115,7 +115,7 @@ fn check_str(cx: &LateContext, span: Span) {
"literal non-ASCII character detected",
&format!(
"Consider replacing the string with:\n\"{}\"",
if cx.current_level(UNICODE_NOT_NFC) == Level::Allow {
if is_allowed(cx, UNICODE_NOT_NFC, id) {
escape(string.chars())
} else {
escape(string.nfc())
@ -123,7 +123,7 @@ fn check_str(cx: &LateContext, span: Span) {
),
);
}
if cx.current_level(NON_ASCII_LITERAL) == Level::Allow && string.chars().zip(string.nfc()).any(|(a, b)| a != b) {
if is_allowed(cx, NON_ASCII_LITERAL, id) && string.chars().zip(string.nfc()).any(|(a, b)| a != b) {
span_help_and_lint(
cx,
UNICODE_NOT_NFC,

View file

@ -4,7 +4,7 @@ use rustc::hir::*;
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc::hir::def::Def;
use rustc::hir::map::Node;
use rustc::lint::{LintContext, LateContext, Level, Lint};
use rustc::lint::{LintContext, Level, LateContext, Lint};
use rustc::session::Session;
use rustc::traits;
use rustc::ty::{self, TyCtxt, Ty};
@ -545,10 +545,7 @@ impl<'a> DiagnosticWrapper<'a> {
}
pub fn span_lint<'a, T: LintContext<'a>>(cx: &T, lint: &'static Lint, sp: Span, msg: &str) {
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
if cx.current_level(lint) != Level::Allow {
db.wiki_link(lint);
}
DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)).wiki_link(lint);
}
pub fn span_help_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
@ -559,10 +556,8 @@ pub fn span_help_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
help: &str,
) {
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
if cx.current_level(lint) != Level::Allow {
db.0.help(help);
db.wiki_link(lint);
}
db.0.help(help);
db.wiki_link(lint);
}
pub fn span_note_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
@ -574,14 +569,12 @@ pub fn span_note_and_lint<'a, 'tcx: 'a, T: LintContext<'tcx>>(
note: &str,
) {
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
if cx.current_level(lint) != Level::Allow {
if note_span == span {
db.0.note(note);
} else {
db.0.span_note(note_span, note);
}
db.wiki_link(lint);
if note_span == span {
db.0.note(note);
} else {
db.0.span_note(note_span, note);
}
db.wiki_link(lint);
}
pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>(
@ -594,10 +587,8 @@ pub fn span_lint_and_then<'a, 'tcx: 'a, T: LintContext<'tcx>, F>(
F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
{
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
if cx.current_level(lint) != Level::Allow {
f(&mut db.0);
db.wiki_link(lint);
}
f(&mut db.0);
db.wiki_link(lint);
}
pub fn span_lint_and_sugg<'a, 'tcx: 'a, T: LintContext<'tcx>>(
@ -1012,3 +1003,10 @@ pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Option<u
layout.size(cx.tcx).bytes()
})
}
/// Returns true if the lint is allowed in the current context
///
/// Useful for skipping long running code when it's unnecessary
pub fn is_allowed(cx: &LateContext, lint: &'static Lint, id: NodeId) -> bool {
cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
}

View file

@ -9,6 +9,8 @@ error: This generic shadows the built-in type `u32`
error[E0308]: mismatched types
--> $DIR/builtin-type-shadow.rs:6:5
|
5 | fn foo<u32>(a: u32) -> u32 {
| --- expected `u32` because of return type
6 | 42
| ^^ expected type parameter, found integral variable
|

View file

@ -75,7 +75,7 @@ impl Unrelated {
#[warn(needless_range_loop, explicit_iter_loop, explicit_into_iter_loop, iter_next_loop, reverse_range_loop, explicit_counter_loop, for_kv_map)]
#[warn(unused_collect)]
#[allow(linkedlist, shadow_unrelated, unnecessary_mut_passed, cyclomatic_complexity, similar_names)]
#[allow(many_single_char_names)]
#[allow(many_single_char_names, unused_variables)]
fn main() {
const MAX_LEN: usize = 42;

View file

@ -84,14 +84,6 @@ help: consider using an iterator
84 | for <item> in &vec {
| ^^^^^^
error: unused variable: `i`
--> $DIR/for_loop.rs:88:9
|
88 | for i in 0..vec.len() {
| ^
|
= note: `-D unused-variables` implied by `-D warnings`
error: the loop variable `i` is only used to index `vec`.
--> $DIR/for_loop.rs:93:5
|
@ -506,5 +498,5 @@ help: use the corresponding method
344 | for k in rm.keys() {
| ^
error: aborting due to 51 previous errors
error: aborting due to 50 previous errors