mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Rustup
This commit is contained in:
parent
0e4c49b145
commit
459cf467c5
10 changed files with 52 additions and 48 deletions
|
@ -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!(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// rs#L246
|
||||
//
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue