|
1 |
| -use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, EarlyContext, EarlyLintPass}; |
2 |
| -use crate::rustc::{declare_tool_lint, lint_array}; |
3 |
| -use crate::rustc::hir::*; |
| 1 | +use crate::utils::{ |
| 2 | + match_qpath, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty, |
| 3 | +}; |
| 4 | +use if_chain::if_chain; |
4 | 5 | use crate::rustc::hir;
|
5 | 6 | use crate::rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
| 7 | +use crate::rustc::hir::*; |
| 8 | +use crate::rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass}; |
| 9 | +use crate::rustc::{declare_tool_lint, lint_array}; |
6 | 10 | use crate::rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
7 |
| -use crate::utils::{match_qpath, paths, span_lint, span_lint_and_sugg}; |
8 |
| -use crate::syntax::symbol::LocalInternedString; |
9 | 11 | use crate::syntax::ast::{Crate as AstCrate, Ident, ItemKind, Name};
|
10 | 12 | use crate::syntax::source_map::Span;
|
11 |
| - |
| 13 | +use crate::syntax::symbol::LocalInternedString; |
12 | 14 |
|
13 | 15 | /// **What it does:** Checks for various things we like to keep tidy in clippy.
|
14 | 16 | ///
|
@@ -65,6 +67,29 @@ declare_clippy_lint! {
|
65 | 67 | "forbid HashMap and HashSet and suggest the FxHash* variants"
|
66 | 68 | }
|
67 | 69 |
|
| 70 | +/// **What it does:** Checks for calls to `cx.span_lint*` and suggests to use the `utils::*` |
| 71 | +/// variant of the function. |
| 72 | +/// |
| 73 | +/// **Why is this bad?** The `utils::*` variants also add a link to the Clippy documentation to the |
| 74 | +/// warning/error messages. |
| 75 | +/// |
| 76 | +/// **Known problems:** None. |
| 77 | +/// |
| 78 | +/// **Example:** |
| 79 | +/// Bad: |
| 80 | +/// ```rust |
| 81 | +/// cx.span_lint(LINT_NAME, "message"); |
| 82 | +/// ``` |
| 83 | +/// |
| 84 | +/// Good: |
| 85 | +/// ```rust |
| 86 | +/// utils::span_lint(cx, LINT_NAME, "message"); |
| 87 | +/// ``` |
| 88 | +declare_clippy_lint! { |
| 89 | + pub COMPILER_LINT_FUNCTIONS, |
| 90 | + internal, |
| 91 | + "usage of the lint functions of the compiler instead of the utils::* variant" |
| 92 | +} |
68 | 93 |
|
69 | 94 | #[derive(Copy, Clone)]
|
70 | 95 | pub struct Clippy;
|
@@ -245,3 +270,48 @@ impl EarlyLintPass for DefaultHashTypes {
|
245 | 270 | }
|
246 | 271 | }
|
247 | 272 | }
|
| 273 | + |
| 274 | +#[derive(Clone, Default)] |
| 275 | +pub struct CompilerLintFunctions { |
| 276 | + map: FxHashMap<String, String>, |
| 277 | +} |
| 278 | + |
| 279 | +impl CompilerLintFunctions { |
| 280 | + pub fn new() -> Self { |
| 281 | + let mut map = FxHashMap::default(); |
| 282 | + map.insert("span_lint".to_string(), "utils::span_lint".to_string()); |
| 283 | + map.insert("struct_span_lint".to_string(), "utils::span_lint".to_string()); |
| 284 | + map.insert("lint".to_string(), "utils::span_lint".to_string()); |
| 285 | + map.insert("span_lint_note".to_string(), "utils::span_note_and_lint".to_string()); |
| 286 | + map.insert("span_lint_help".to_string(), "utils::span_help_and_lint".to_string()); |
| 287 | + Self { map } |
| 288 | + } |
| 289 | +} |
| 290 | + |
| 291 | +impl LintPass for CompilerLintFunctions { |
| 292 | + fn get_lints(&self) -> LintArray { |
| 293 | + lint_array!(COMPILER_LINT_FUNCTIONS) |
| 294 | + } |
| 295 | +} |
| 296 | + |
| 297 | +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions { |
| 298 | + fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) { |
| 299 | + if_chain! { |
| 300 | + if let ExprKind::MethodCall(ref path, _, ref args) = expr.node; |
| 301 | + let fn_name = path.ident.as_str().to_string(); |
| 302 | + if let Some(sugg) = self.map.get(&fn_name); |
| 303 | + let ty = walk_ptrs_ty(cx.tables.expr_ty(&args[0])); |
| 304 | + if match_type(cx, ty, &paths::EARLY_CONTEXT) |
| 305 | + || match_type(cx, ty, &paths::LATE_CONTEXT); |
| 306 | + then { |
| 307 | + span_help_and_lint( |
| 308 | + cx, |
| 309 | + COMPILER_LINT_FUNCTIONS, |
| 310 | + path.ident.span, |
| 311 | + "usage of a compiler lint function", |
| 312 | + &format!("Please use the Clippy variant of this function: `{}`", sugg), |
| 313 | + ); |
| 314 | + } |
| 315 | + } |
| 316 | + } |
| 317 | +} |
0 commit comments