From 703c733cb3ce1ea2f9de0ebbcd8d92602e146d93 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Sat, 27 Mar 2021 18:27:20 -0500 Subject: [PATCH] Experiment with external lint docs --- .../docs/correctness/APPROX_CONSTANT.md | 24 +++++++++++++++++ .../docs/restriction/INTEGER_ARITHMETIC.md | 19 ++++++++++++++ clippy_lints/src/approx_const.rs | 26 +------------------ clippy_lints/src/arithmetic.rs | 21 +-------------- clippy_lints/src/lib.rs | 11 ++++++++ util/lintlib.py | 10 +++++++ 6 files changed, 66 insertions(+), 45 deletions(-) create mode 100644 clippy_lints/docs/correctness/APPROX_CONSTANT.md create mode 100644 clippy_lints/docs/restriction/INTEGER_ARITHMETIC.md diff --git a/clippy_lints/docs/correctness/APPROX_CONSTANT.md b/clippy_lints/docs/correctness/APPROX_CONSTANT.md new file mode 100644 index 000000000000..f1ccf9039c30 --- /dev/null +++ b/clippy_lints/docs/correctness/APPROX_CONSTANT.md @@ -0,0 +1,24 @@ +**What it does:** Checks for floating point literals that approximate +constants which are defined in +[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) +or +[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), +respectively, suggesting to use the predefined constant. + +**Why is this bad?** Usually, the definition in the standard library is more +precise than what people come up with. If you find that your definition is +actually more precise, please [file a Rust +issue](https://github.com/rust-lang/rust/issues). + +**Known problems:** None. + +**Example:** +```rust +let x = 3.14; +let y = 1_f64 / x; +``` +Use predefined constants instead: +```rust +let x = std::f32::consts::PI; +let y = std::f64::consts::FRAC_1_PI; +``` diff --git a/clippy_lints/docs/restriction/INTEGER_ARITHMETIC.md b/clippy_lints/docs/restriction/INTEGER_ARITHMETIC.md new file mode 100644 index 000000000000..32088954c958 --- /dev/null +++ b/clippy_lints/docs/restriction/INTEGER_ARITHMETIC.md @@ -0,0 +1,19 @@ +**What it does:** Checks for integer arithmetic operations which could overflow or panic. + +Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable +of overflowing according to the [Rust +Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow), +or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is +attempted. + +**Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in +release mode. Division by zero will cause a panic in either mode. In some applications one +wants explicitly checked, wrapping or saturating arithmetic. + +**Known problems:** None. + +**Example:** +```rust +# let a = 0; +a + 1; +``` diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs index 3d04abe094d7..e7eb8c2360c4 100644 --- a/clippy_lints/src/approx_const.rs +++ b/clippy_lints/src/approx_const.rs @@ -6,31 +6,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol; use std::f64::consts as f64; -declare_clippy_lint! { - /// **What it does:** Checks for floating point literals that approximate - /// constants which are defined in - /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants) - /// or - /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants), - /// respectively, suggesting to use the predefined constant. - /// - /// **Why is this bad?** Usually, the definition in the standard library is more - /// precise than what people come up with. If you find that your definition is - /// actually more precise, please [file a Rust - /// issue](https://github.com/rust-lang/rust/issues). - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// let x = 3.14; - /// let y = 1_f64 / x; - /// ``` - /// Use predefined constants instead: - /// ```rust - /// let x = std::f32::consts::PI; - /// let y = std::f64::consts::FRAC_1_PI; - /// ``` +declare_clippy_lint_new! { pub APPROX_CONSTANT, correctness, "the approximate of a known float constant (in `std::fXX::consts`)" diff --git a/clippy_lints/src/arithmetic.rs b/clippy_lints/src/arithmetic.rs index c560f545d6a6..2d3d42fb371e 100644 --- a/clippy_lints/src/arithmetic.rs +++ b/clippy_lints/src/arithmetic.rs @@ -5,26 +5,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::source_map::Span; -declare_clippy_lint! { - /// **What it does:** Checks for integer arithmetic operations which could overflow or panic. - /// - /// Specifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable - /// of overflowing according to the [Rust - /// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow), - /// or which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is - /// attempted. - /// - /// **Why is this bad?** Integer overflow will trigger a panic in debug builds or will wrap in - /// release mode. Division by zero will cause a panic in either mode. In some applications one - /// wants explicitly checked, wrapping or saturating arithmetic. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// # let a = 0; - /// a + 1; - /// ``` +declare_clippy_lint_new! { pub INTEGER_ARITHMETIC, restriction, "any integer arithmetic expression which could overflow or panic" diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index f013613119cf..6af70242c494 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -3,6 +3,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(drain_filter)] +#![feature(extended_key_value_attributes)] #![feature(in_band_lifetimes)] #![feature(once_cell)] #![feature(rustc_private)] @@ -145,6 +146,16 @@ macro_rules! declare_clippy_lint { }; } +macro_rules! declare_clippy_lint_new { + { $(#[$attr:meta])* pub $name:tt, $category:tt $($tail:tt)* } => { + declare_clippy_lint! { + #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/docs/", + stringify!($category), "/", stringify!($name), ".md"))] + $(#[$attr])* pub $name, $category $($tail)* + } + }; +} + #[macro_export] macro_rules! sym { ( $($x:tt)* ) => { clippy_utils::sym!($($x)*) } diff --git a/util/lintlib.py b/util/lintlib.py index d0d9beb9b2d9..97217ffdb8e4 100644 --- a/util/lintlib.py +++ b/util/lintlib.py @@ -33,6 +33,7 @@ def parse_lints(lints, filepath): comment = [] clippy = False deprecated = False + externaldoc = False name = "" with open(filepath) as fp: @@ -60,11 +61,14 @@ def parse_lints(lints, filepath): log.info("found %s with level %s in %s", name, level, filepath) + if externaldoc: + comment = open(f"clippy_lints/docs/{group}/{name}.md").read().splitlines() lints.append(Lint(name, level, comment, filepath, group)) comment = [] clippy = False deprecated = False + externaldoc = False name = "" else: m = comment_re.search(line) @@ -73,9 +77,15 @@ def parse_lints(lints, filepath): elif line.startswith("declare_clippy_lint!"): clippy = True deprecated = False + externaldoc = False + elif line.startswith("declare_clippy_lint_new!"): + clippy = True + deprecated = False + externaldoc = True elif line.startswith("declare_deprecated_lint!"): clippy = False deprecated = True + externaldoc = False elif line.startswith("declare_lint!"): import sys print(