diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 04239b797e3b..d60627292ed2 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -997,6 +997,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box let_underscore::LetUnderscore); store.register_late_pass(|| box atomic_ordering::AtomicOrdering); store.register_early_pass(|| box single_component_path_imports::SingleComponentPathImports); + store.register_early_pass(|| box utils::internal_lints::CollapsibleCalls); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1098,6 +1099,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&utils::internal_lints::OUTER_EXPN_EXPN_DATA), LintId::of(&utils::internal_lints::PRODUCE_ICE), LintId::of(&utils::internal_lints::DEFAULT_LINT), + LintId::of(&utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS), ]); store.register_group(true, "clippy::all", Some("clippy"), vec![ diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs index cc8cb3a7adf1..96993bc690d0 100644 --- a/clippy_lints/src/utils/internal_lints.rs +++ b/clippy_lints/src/utils/internal_lints.rs @@ -19,6 +19,7 @@ use syntax::ast; use syntax::ast::{Crate as AstCrate, ItemKind, LitKind, Name, Expr as AstExpr}; use syntax::ptr::P; use syntax::visit::FnKind; +use std::borrow::Cow; declare_clippy_lint! { /// **What it does:** Checks for various things we like to keep tidy in clippy. @@ -409,44 +410,41 @@ impl EarlyLintPass for CollapsibleCalls { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &AstExpr) { use ast::{StmtKind, ExprKind}; - span_lint_and_help(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.span, "lint message", "help message"); - - // if_chain! { - // if let ExprKind::Call(ref func, ref and_then_args) = expr.kind; - // if let ExprKind::Path(None, ref path) = func.kind; - // if match_path_ast(path, &["span_lint_and_then"]); - // if and_then_args.len() == 5; - // if let ExprKind::Closure(_, _, _, _, block, _) = &and_then_args[4].kind; - // if let ExprKind::Block(block, _) = &block.kind; - // let stmts = &block.stmts; - // if stmts.len() == 1; - // if let StmtKind::Expr(only_expr) = &stmts[0].kind; - // if let ExprKind::MethodCall(ref ps, ref span_call_args) = &only_expr.kind; - // let and_then_args = get_and_then_args(cx, and_then_args); - // then { - // match &*ps.ident.as_str() { - // "span_suggestion" => - // suggest_span_suggestion(cx, expr, and_then_args, suggestion_args(cx, span_call_args)), - // "span_help" => - // suggest_span_help(cx, expr, and_then_args, help_args(cx, span_call_args)), - // "span_note" => - // suggest_span_note(cx, expr, and_then_args, note_args(cx, span_call_args)), - // _ => (), - // } - // span_lint_and_help(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.span, "lint message", "help message"); - // } - // } + if_chain! { + if let ExprKind::Call(ref func, ref and_then_args) = expr.kind; + if let ExprKind::Path(None, ref path) = func.kind; + if match_path_ast(path, &["span_lint_and_then"]); + if and_then_args.len() == 5; + if let ExprKind::Closure(_, _, _, _, block, _) = &and_then_args[4].kind; + if let ExprKind::Block(block, _) = &block.kind; + let stmts = &block.stmts; + if stmts.len() == 1; + if let StmtKind::Expr(only_expr) = &stmts[0].kind; + if let ExprKind::MethodCall(ref ps, ref span_call_args) = &only_expr.kind; + let and_then_args = get_and_then_args(cx, and_then_args); + then { + match &*ps.ident.as_str() { + "span_suggestion" => + suggest_span_suggestion(cx, expr, and_then_args, suggestion_args(cx, span_call_args)), + "span_help" => + suggest_span_help(cx, expr, and_then_args, help_args(cx, span_call_args)), + "span_note" => + suggest_span_note(cx, expr, and_then_args, note_args(cx, span_call_args)), + _ => (), + } + } + } } } -struct AndThenArgs { +struct AndThenArgs<'a> { cx: Cow<'a, str>, lint: Cow<'a, str>, span: Cow<'a, str>, msg: Cow<'a, str>, } -fn get_and_then_args(cx: &EarlyContext<'_>, and_then_args: &Vec>) -> AndThenArgs { +fn get_and_then_args<'a>(cx: &EarlyContext<'_>, and_then_args: &Vec>) -> AndThenArgs<'a>{ let cx_snippet = snippet(cx, and_then_args[0].span); let lint_snippet= snippet(cx, and_then_args[1].span); let span_snippet = snippet(cx, and_then_args[2].span); @@ -460,14 +458,14 @@ fn get_and_then_args(cx: &EarlyContext<'_>, and_then_args: &Vec>) -> } } -struct SuggestionArgs { +struct SuggestionArgs<'a> { span: Cow<'a, str>, help: Cow<'a, str>, sugg: Cow<'a, str>, applicability: Cow<'a, str>, } -fn suggestion_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> SuggestionArgs { +fn suggestion_args<'a>(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> SuggestionArgs<'a> { let span_snippet_of_span_call = snippet(cx, span_call_args[0].span); let help_snippet = snippet(cx, span_call_args[1].span); let sugg_snippet = snippet(cx, span_call_args[2].span); @@ -481,7 +479,7 @@ fn suggestion_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> S } } -fn suggest_span_suggestion(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs, suggestion_args: SuggestionArgs) { +fn suggest_span_suggestion(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs<'_>, suggestion_args: SuggestionArgs<'_>) { if and_then_args.span == suggestion_args.span { println!("suggestion true"); span_lint_and_sugg ( @@ -505,12 +503,12 @@ fn suggest_span_suggestion(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: } } -struct HelpArgs { +struct HelpArgs<'a> { span: Cow<'a, str>, help: Cow<'a, str>, } -fn help_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> HelpArgs { +fn help_args<'a>(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> HelpArgs<'a>{ let span_snippet_of_span_call = snippet(cx, span_call_args[0].span); let help_snippet = snippet(cx, span_call_args[1].span); @@ -520,7 +518,7 @@ fn help_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> HelpArg } } -fn suggest_span_help(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs, help_args: HelpArgs) { +fn suggest_span_help(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs<'_>, help_args: HelpArgs<'_>) { if and_then_args.span == help_args.span { span_lint_and_sugg( cx, @@ -541,12 +539,12 @@ fn suggest_span_help(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndTh } } -struct NoteArgs { +struct NoteArgs<'a> { span: Cow<'a, str>, note: Cow<'a, str>, } -fn note_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> NoteArgs { +fn note_args<'a>(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> NoteArgs<'a> { let span_snippet_of_span_call = snippet(cx, span_call_args[0].span); let note_snippet = snippet(cx, span_call_args[1].span); @@ -556,7 +554,7 @@ fn note_args(cx: &EarlyContext<'_>, span_call_args: &Vec>) -> NoteArg } } -fn suggest_span_note(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs, note_args: NoteArgs) { +fn suggest_span_note(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndThenArgs<'_> , note_args: NoteArgs<'_> ) { if and_then_args.span == note_args.span { span_lint_and_sugg( cx, @@ -577,6 +575,6 @@ fn suggest_span_note(cx: &EarlyContext<'_>, expr: &AstExpr, and_then_args: AndTh } } -fn snippet(cx: &EarlyContext<'_>, span: Span) -> Cow<'a, str> { +fn snippet<'a>(cx: &EarlyContext<'_>, span: Span) -> Cow<'a, str> { other_snippet(cx, span, "Should not be") }