about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/Cargo.toml1
-rw-r--r--clippy_lints/src/declare_clippy_lint.rs162
-rw-r--r--clippy_lints/src/lib.rs6
-rw-r--r--clippy_utils/src/lib.rs2
-rw-r--r--declare_clippy_lint/Cargo.toml13
-rw-r--r--declare_clippy_lint/src/lib.rs182
-rw-r--r--tests/versioncheck.rs1
7 files changed, 167 insertions, 200 deletions
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index d1188940b46..55f1d31b4ad 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -13,7 +13,6 @@ arrayvec = { version = "0.7", default-features = false }
 cargo_metadata = "0.18"
 clippy_config = { path = "../clippy_config" }
 clippy_utils = { path = "../clippy_utils" }
-declare_clippy_lint = { path = "../declare_clippy_lint" }
 itertools = "0.12"
 quine-mc_cluskey = "0.2"
 regex-syntax = "0.8"
diff --git a/clippy_lints/src/declare_clippy_lint.rs b/clippy_lints/src/declare_clippy_lint.rs
new file mode 100644
index 00000000000..b1e39c70baa
--- /dev/null
+++ b/clippy_lints/src/declare_clippy_lint.rs
@@ -0,0 +1,162 @@
+#[macro_export]
+#[allow(clippy::crate_in_macro_def)]
+macro_rules! declare_clippy_lint {
+    (@
+        $(#[doc = $lit:literal])*
+        pub $lint_name:ident,
+        $category:ident,
+        $lintcategory:expr,
+        $desc:literal,
+        $version_expr:expr,
+        $version_lit:literal
+    ) => {
+        rustc_session::declare_tool_lint! {
+            $(#[doc = $lit])*
+            #[clippy::version = $version_lit]
+            pub clippy::$lint_name,
+            $category,
+            $desc,
+            report_in_external_macro:true
+        }
+
+        pub(crate) static ${concat($lint_name, _INFO)}: &'static crate::LintInfo = &crate::LintInfo {
+            lint: &$lint_name,
+            category:  $lintcategory,
+            explanation: concat!($($lit,"\n",)*),
+            location: concat!(file!(), "#L", line!()),
+            version: $version_expr
+        };
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        restriction,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Allow, crate::LintCategory::Restriction, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        style,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Warn, crate::LintCategory::Style, $desc,
+            Some($version), $version
+
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        correctness,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Deny, crate::LintCategory::Correctness, $desc,
+            Some($version), $version
+
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        perf,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Warn, crate::LintCategory::Perf, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        complexity,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Warn, crate::LintCategory::Complexity, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        suspicious,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        nursery,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Allow, crate::LintCategory::Nursery, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        pedantic,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc,
+            Some($version), $version
+        }
+    };
+    (
+        $(#[doc = $lit:literal])*
+        #[clippy::version = $version:literal]
+        pub $lint_name:ident,
+        cargo,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Allow, crate::LintCategory::Cargo, $desc,
+            Some($version), $version
+        }
+    };
+
+    (
+        $(#[doc = $lit:literal])*
+        pub $lint_name:ident,
+        internal,
+        $desc:literal
+    ) => {
+        declare_clippy_lint! {@
+            $(#[doc = $lit])*
+            pub $lint_name, Allow, crate::LintCategory::Internal, $desc,
+            None, "0.0.0"
+        }
+    };
+}
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 1d41f568f37..efc9fe6f315 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -1,6 +1,7 @@
 #![feature(array_windows)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(box_patterns)]
+#![feature(macro_metavar_expr_concat)]
 #![feature(control_flow_enum)]
 #![feature(f128)]
 #![feature(f16)]
@@ -59,9 +60,10 @@ extern crate rustc_trait_selection;
 extern crate thin_vec;
 
 #[macro_use]
-extern crate clippy_utils;
+mod declare_clippy_lint;
+
 #[macro_use]
-extern crate declare_clippy_lint;
+extern crate clippy_utils;
 
 #[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
 mod utils;
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index a925549b0bf..bf7484f7902 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(f128)]
 #![feature(f16)]
 #![feature(if_let_guard)]
+#![feature(macro_metavar_expr_concat)]
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustc_private)]
@@ -129,7 +130,6 @@ use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
 use crate::higher::Range;
 use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
 use crate::visitors::for_each_expr_without_closures;
-
 use rustc_middle::hir::nested_filter;
 
 #[macro_export]
diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml
deleted file mode 100644
index 67a1f7cc72c..00000000000
--- a/declare_clippy_lint/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "declare_clippy_lint"
-version = "0.1.83"
-edition = "2021"
-publish = false
-
-[lib]
-proc-macro = true
-
-[dependencies]
-itertools = "0.12"
-quote = "1.0.21"
-syn = "2.0"
diff --git a/declare_clippy_lint/src/lib.rs b/declare_clippy_lint/src/lib.rs
deleted file mode 100644
index fefc1a0a6c4..00000000000
--- a/declare_clippy_lint/src/lib.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-#![feature(let_chains, proc_macro_span)]
-// warn on lints, that are included in `rust-lang/rust`s bootstrap
-#![warn(rust_2018_idioms, unused_lifetimes)]
-
-use proc_macro::TokenStream;
-use quote::{format_ident, quote};
-use syn::parse::{Parse, ParseStream};
-use syn::{Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta, Result, Token, parse_macro_input};
-
-fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) -> Option<LitStr> {
-    if let Meta::NameValue(name_value) = &attr.meta {
-        let path_idents = name_value.path.segments.iter().map(|segment| &segment.ident);
-
-        if itertools::equal(path_idents, path)
-            && let Expr::Lit(ExprLit { lit: Lit::Str(s), .. }) = &name_value.value
-        {
-            return Some(s.clone());
-        }
-    }
-
-    None
-}
-
-struct ClippyLint {
-    attrs: Vec<Attribute>,
-    version: Option<LitStr>,
-    explanation: String,
-    name: Ident,
-    category: Ident,
-    description: LitStr,
-}
-
-impl Parse for ClippyLint {
-    fn parse(input: ParseStream<'_>) -> Result<Self> {
-        let attrs = input.call(Attribute::parse_outer)?;
-
-        let mut in_code = false;
-        let mut explanation = String::new();
-        let mut version = None;
-        for attr in &attrs {
-            if let Some(lit) = parse_attr(["doc"], attr) {
-                let value = lit.value();
-                let line = value.strip_prefix(' ').unwrap_or(&value);
-
-                if let Some(lang) = line.strip_prefix("```") {
-                    let tag = lang.split_once(',').map_or(lang, |(left, _)| left);
-                    if !in_code && matches!(tag, "" | "rust" | "ignore" | "should_panic" | "no_run" | "compile_fail") {
-                        explanation += "```rust\n";
-                    } else {
-                        explanation += line;
-                        explanation.push('\n');
-                    }
-                    in_code = !in_code;
-                } else if !(in_code && line.starts_with("# ")) {
-                    explanation += line;
-                    explanation.push('\n');
-                }
-            } else if let Some(lit) = parse_attr(["clippy", "version"], attr) {
-                if let Some(duplicate) = version.replace(lit) {
-                    return Err(Error::new_spanned(duplicate, "duplicate clippy::version"));
-                }
-            } else {
-                return Err(Error::new_spanned(attr, "unexpected attribute"));
-            }
-        }
-
-        input.parse::<Token![pub]>()?;
-        let name = input.parse()?;
-        input.parse::<Token![,]>()?;
-
-        let category = input.parse()?;
-        input.parse::<Token![,]>()?;
-
-        let description = input.parse()?;
-
-        Ok(Self {
-            attrs,
-            version,
-            explanation,
-            name,
-            category,
-            description,
-        })
-    }
-}
-
-/// Macro used to declare a Clippy lint.
-///
-/// Every lint declaration consists of 4 parts:
-///
-/// 1. The documentation, which is used for the website and `cargo clippy --explain`
-/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
-/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
-///    `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
-/// 4. The `description` that contains a short explanation on what's wrong with code where the lint
-///    is triggered.
-///
-/// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are
-/// enabled by default. As said in the README.md of this repository, if the lint level mapping
-/// changes, please update README.md.
-///
-/// # Example
-///
-/// ```ignore
-/// use rustc_session::declare_tool_lint;
-///
-/// declare_clippy_lint! {
-///     /// ### What it does
-///     /// Checks for ... (describe what the lint matches).
-///     ///
-///     /// ### Why is this bad?
-///     /// Supply the reason for linting the code.
-///     ///
-///     /// ### Example
-///     /// ```rust
-///     /// Insert a short example of code that triggers the lint
-///     /// ```
-///     ///
-///     /// Use instead:
-///     /// ```rust
-///     /// Insert a short example of improved code that doesn't trigger the lint
-///     /// ```
-///     #[clippy::version = "1.65.0"]
-///     pub LINT_NAME,
-///     pedantic,
-///     "description"
-/// }
-/// ```
-/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
-#[proc_macro]
-pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
-    let ClippyLint {
-        attrs,
-        version,
-        explanation,
-        name,
-        category,
-        description,
-    } = parse_macro_input!(input as ClippyLint);
-
-    let mut category = category.to_string();
-
-    let level = format_ident!("{}", match category.as_str() {
-        "correctness" => "Deny",
-        "style" | "suspicious" | "complexity" | "perf" => "Warn",
-        "pedantic" | "restriction" | "cargo" | "nursery" | "internal" => "Allow",
-        _ => panic!("unknown category {category}"),
-    },);
-
-    let info_name = format_ident!("{name}_INFO");
-
-    (&mut category[0..1]).make_ascii_uppercase();
-    let category_variant = format_ident!("{category}");
-
-    let name_span = name.span().unwrap();
-    let location = format!("{}#L{}", name_span.source_file().path().display(), name_span.line());
-
-    let version = match version {
-        Some(version) => quote!(Some(#version)),
-        None => quote!(None),
-    };
-
-    let output = quote! {
-        rustc_session::declare_tool_lint! {
-            #(#attrs)*
-            pub clippy::#name,
-            #level,
-            #description,
-            report_in_external_macro: true
-        }
-
-        pub(crate) static #info_name: &'static crate::LintInfo = &crate::LintInfo {
-            lint: &#name,
-            category: crate::LintCategory::#category_variant,
-            explanation: #explanation,
-            location: #location,
-            version: #version,
-        };
-    };
-
-    TokenStream::from(output)
-}
diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs
index 68328333937..e29898f068d 100644
--- a/tests/versioncheck.rs
+++ b/tests/versioncheck.rs
@@ -24,7 +24,6 @@ fn consistent_clippy_crate_versions() {
     let clippy_version = read_version("Cargo.toml");
 
     let paths = [
-        "declare_clippy_lint/Cargo.toml",
         "clippy_config/Cargo.toml",
         "clippy_lints/Cargo.toml",
         "clippy_utils/Cargo.toml",