From 5053db7c006a22060fc87c227339ddc6ee8d8ec0 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 30 Dec 2020 13:49:28 -0500 Subject: [PATCH 1/4] Don't make tools responsible for checking unknown and renamed lints Previously, clippy (and any other tool emitting lints) had to have their own separate UNKNOWN_LINTS pass, because the compiler assumed any tool lint could be valid. Now, as long as any lint starting with the tool prefix exists, the compiler will warn when an unknown lint is present. --- compiler/rustc_lint/src/context.rs | 39 +++++++++++++++++++----------- compiler/rustc_lint/src/levels.rs | 5 ++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 0f40324acb11c..c4df0acbbb0f9 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -354,10 +354,23 @@ impl LintStore { lint_name.to_string() }; // If the lint was scoped with `tool::` check if the tool lint exists - if tool_name.is_some() { + if let Some(tool_name) = tool_name { match self.by_name.get(&complete_name) { None => match self.lint_groups.get(&*complete_name) { - None => return CheckLintNameResult::Tool(Err((None, String::new()))), + // If the lint isn't registered, there are two possibilities: + None => { + // 1. The tool is currently running, so this lint really doesn't exist. + // FIXME: should this handle tools that never register a lint, like rustfmt? + tracing::debug!("lints={:?}", self.by_name.keys().collect::>()); + let tool_prefix = format!("{}::", tool_name); + return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) { + self.no_lint_suggestion(&complete_name) + } else { + // 2. The tool isn't currently running, so no lints will be registered. + // To avoid giving a false positive, ignore all unknown lints. + CheckLintNameResult::Tool(Err((None, String::new()))) + }; + } Some(LintGroup { lint_ids, .. }) => { return CheckLintNameResult::Tool(Ok(&lint_ids)); } @@ -398,6 +411,15 @@ impl LintStore { } } + fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> { + let symbols = self.by_name.keys().map(|name| Symbol::intern(&name)).collect::>(); + + let suggestion = + find_best_match_for_name(&symbols, Symbol::intern(&lint_name.to_lowercase()), None); + + CheckLintNameResult::NoLint(suggestion) + } + fn check_tool_name_for_backwards_compat( &self, lint_name: &str, @@ -407,18 +429,7 @@ impl LintStore { match self.by_name.get(&complete_name) { None => match self.lint_groups.get(&*complete_name) { // Now we are sure, that this lint exists nowhere - None => { - let symbols = - self.by_name.keys().map(|name| Symbol::intern(&name)).collect::>(); - - let suggestion = find_best_match_for_name( - &symbols, - Symbol::intern(&lint_name.to_lowercase()), - None, - ); - - CheckLintNameResult::NoLint(suggestion) - } + None => self.no_lint_suggestion(lint_name), Some(LintGroup { lint_ids, depr, .. }) => { // Reaching this would be weird, but let's cover this case anyway if let Some(LintAlias { name, silent }) = depr { diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 37bdc878b16cd..fc8f84461f991 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -381,6 +381,11 @@ impl<'s> LintLevelsBuilder<'s> { src, Some(li.span().into()), |lint| { + let name = if let Some(tool_name) = tool_name { + format!("{}::{}", tool_name, name) + } else { + name.to_string() + }; let mut db = lint.build(&format!("unknown lint: `{}`", name)); if let Some(suggestion) = suggestion { db.span_suggestion( From c819a4c0255fc8857ebadb74763edd9b9f9c9601 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 15 Jan 2021 15:21:20 -0500 Subject: [PATCH 2/4] Don't mark `ineffective_unstable_trait_impl` as an internal lint It's not an internal lint: - It's not in the rustc::internal lint group - It's on unconditionally, because it actually lints `staged_api`, not the compiler This fixes a bug where `#[deny(rustc::internal)]` would warn that `rustc::internal` was an unknown lint. --- compiler/rustc_lint_defs/src/builtin.rs | 27 ++++++++++++++++--- library/alloc/src/task.rs | 6 +++-- .../stability-attribute-trait-impl.rs | 2 +- .../stability-attribute-trait-impl.stderr | 2 +- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e963279670411..20052ad9bfcbd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4,7 +4,7 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::{declare_lint, declare_lint_pass, declare_tool_lint}; +use crate::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; use rustc_span::symbol::sym; @@ -2825,8 +2825,29 @@ declare_lint! { }; } -declare_tool_lint! { - pub rustc::INEFFECTIVE_UNSTABLE_TRAIT_IMPL, +declare_lint! { + /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used. + /// + /// ### Example + /// + /// ```compile_fail + /// #![feature(staged_api)] + /// + /// #[derive(Clone)] + /// #[stable(feature = "x", since = "1")] + /// struct S {} + /// + /// #[unstable(feature = "y", issue = "none")] + /// impl Copy for S {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// `staged_api` does not currently support using a stability attribute on `impl` blocks. + /// `impl`s are always stable if both the type and trait are stable, and always unstable otherwise. + pub INEFFECTIVE_UNSTABLE_TRAIT_IMPL, Deny, "detects `#[unstable]` on stable trait implementations for stable types" } diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index fcab3fd0badce..69690494196bf 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -33,7 +33,8 @@ pub trait Wake { } } -#[allow(rustc::ineffective_unstable_trait_impl)] +#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))] +#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))] #[unstable(feature = "wake_trait", issue = "69912")] impl From> for Waker { fn from(waker: Arc) -> Waker { @@ -43,7 +44,8 @@ impl From> for Waker { } } -#[allow(rustc::ineffective_unstable_trait_impl)] +#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))] +#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))] #[unstable(feature = "wake_trait", issue = "69912")] impl From> for RawWaker { fn from(waker: Arc) -> RawWaker { diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs b/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs index cc57071b87cea..656564fc9e3f8 100644 --- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs +++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.rs @@ -22,7 +22,7 @@ impl StableTrait for UnstableType {} impl UnstableTrait for StableType {} #[unstable(feature = "x", issue = "none")] -//~^ ERROR an `#[unstable]` annotation here has no effect [rustc::ineffective_unstable_trait_impl] +//~^ ERROR an `#[unstable]` annotation here has no effect [ineffective_unstable_trait_impl] impl StableTrait for StableType {} fn main() {} diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr index 1915d03fb0aaf..a11479cc8f45c 100644 --- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr @@ -4,7 +4,7 @@ error: an `#[unstable]` annotation here has no effect LL | #[unstable(feature = "x", issue = "none")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(rustc::ineffective_unstable_trait_impl)]` on by default + = note: `#[deny(ineffective_unstable_trait_impl)]` on by default = note: see issue #55436 for more information error: aborting due to previous error From 5e3df4266aa31a688ac0909a0a7845bca7e563c0 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Sat, 16 Jan 2021 17:11:26 +0100 Subject: [PATCH 3/4] More advanced unknown lint suggestion This copies the unknown_lints code clippy uses for its unknown_clippy_lints lint to rustc. The unknown_clippy_lints code is more advanced, because it doesn't suggest renamed or removed lints and correctly suggest lower casing lints. --- compiler/rustc_lint/src/context.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c4df0acbbb0f9..3971a3099823f 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -412,12 +412,18 @@ impl LintStore { } fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> { - let symbols = self.by_name.keys().map(|name| Symbol::intern(&name)).collect::>(); + let name_lower = lint_name.to_lowercase(); + let symbols = + self.get_lints().iter().map(|l| Symbol::intern(&l.name_lower())).collect::>(); - let suggestion = - find_best_match_for_name(&symbols, Symbol::intern(&lint_name.to_lowercase()), None); - - CheckLintNameResult::NoLint(suggestion) + if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() { + // First check if the lint name is (partly) in upper case instead of lower case... + CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower))) + } else { + // ...if not, search for lints with a similar name + let suggestion = find_best_match_for_name(&symbols, Symbol::intern(&name_lower), None); + CheckLintNameResult::NoLint(suggestion) + } } fn check_tool_name_for_backwards_compat( From 13728b8975bf53171cdd94d5edfffb78a2a9179f Mon Sep 17 00:00:00 2001 From: flip1995 Date: Sat, 16 Jan 2021 17:30:31 +0100 Subject: [PATCH 4/4] Deprecate unknown_clippy_lints This is now handled by unknown_lints --- src/tools/clippy/clippy_lints/src/attrs.rs | 72 +------------------ .../clippy_lints/src/deprecated_lints.rs | 13 ++++ src/tools/clippy/clippy_lints/src/lib.rs | 7 +- src/tools/clippy/tests/ui/deprecated.rs | 1 + src/tools/clippy/tests/ui/deprecated.stderr | 8 ++- .../tests/ui/unknown_clippy_lints.stderr | 40 ++++++----- 6 files changed, 50 insertions(+), 91 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs index 3edbe723922f8..7607394b2fe96 100644 --- a/src/tools/clippy/clippy_lints/src/attrs.rs +++ b/src/tools/clippy/clippy_lints/src/attrs.rs @@ -10,11 +10,10 @@ use rustc_errors::Applicability; use rustc_hir::{ Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind, }; -use rustc_lint::{CheckLintNameResult, EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; +use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::Span; use rustc_span::sym; use rustc_span::symbol::{Symbol, SymbolStr}; @@ -156,33 +155,6 @@ declare_clippy_lint! { "empty line after outer attribute" } -declare_clippy_lint! { - /// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy - /// lints and if those lints exist in clippy. If there is an uppercase letter in the lint name - /// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase - /// the lint name. - /// - /// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// Bad: - /// ```rust - /// #![warn(if_not_els)] - /// #![deny(clippy::All)] - /// ``` - /// - /// Good: - /// ```rust - /// #![warn(if_not_else)] - /// #![deny(clippy::all)] - /// ``` - pub UNKNOWN_CLIPPY_LINTS, - style, - "unknown_lints for scoped Clippy lints" -} - declare_clippy_lint! { /// **What it does:** Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category. /// @@ -272,7 +244,6 @@ declare_lint_pass!(Attributes => [ INLINE_ALWAYS, DEPRECATED_SEMVER, USELESS_ATTRIBUTE, - UNKNOWN_CLIPPY_LINTS, BLANKET_CLIPPY_RESTRICTION_LINTS, ]); @@ -409,48 +380,9 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option { } fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) { - let lint_store = cx.lints(); for lint in items { if let Some(lint_name) = extract_clippy_lint(lint) { - if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name(&lint_name, Some(sym::clippy)) - { - span_lint_and_then( - cx, - UNKNOWN_CLIPPY_LINTS, - lint.span(), - &format!("unknown clippy lint: clippy::{}", lint_name), - |diag| { - let name_lower = lint_name.to_lowercase(); - let symbols = lint_store - .get_lints() - .iter() - .map(|l| Symbol::intern(&l.name_lower())) - .collect::>(); - let sugg = find_best_match_for_name( - &symbols, - Symbol::intern(&format!("clippy::{}", name_lower)), - None, - ); - if lint_name.chars().any(char::is_uppercase) - && lint_store.find_lints(&format!("clippy::{}", name_lower)).is_ok() - { - diag.span_suggestion( - lint.span(), - "lowercase the lint name", - format!("clippy::{}", name_lower), - Applicability::MachineApplicable, - ); - } else if let Some(sugg) = sugg { - diag.span_suggestion( - lint.span(), - "did you mean", - sugg.to_string(), - Applicability::MachineApplicable, - ); - } - }, - ); - } else if lint_name == "restriction" && ident != "allow" { + if lint_name == "restriction" && ident != "allow" { span_lint_and_help( cx, BLANKET_CLIPPY_RESTRICTION_LINTS, diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index bec0c9f93a0d2..47b3cc3ad3038 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -163,6 +163,19 @@ declare_deprecated_lint! { } declare_deprecated_lint! { + /// **What it does:** Nothing. This lint has been deprecated. + /// + /// **Deprecation reason:** This lint has been uplifted to rustc and is now called + /// `panic_fmt`. pub PANIC_PARAMS, "this lint has been uplifted to rustc and is now called `panic_fmt`" } + +declare_deprecated_lint! { + /// **What it does:** Nothing. This lint has been deprecated. + /// + /// **Deprecation reason:** This lint has been integrated into the `unknown_lints` + /// rustc lint. + pub UNKNOWN_CLIPPY_LINTS, + "this lint has been integrated into the `unknown_lints` rustc lint" +} diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 35b057d7b6a41..aaa17561f06d3 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -500,6 +500,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: "clippy::panic_params", "this lint has been uplifted to rustc and is now called `panic_fmt`", ); + store.register_removed( + "clippy::unknown_clippy_lints", + "this lint has been integrated into the `unknown_lints` rustc lint", + ); // end deprecated lints, do not remove this comment, it’s used in `update_lints` // begin register lints, do not remove this comment, it’s used in `update_lints` @@ -541,7 +545,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &attrs::EMPTY_LINE_AFTER_OUTER_ATTR, &attrs::INLINE_ALWAYS, &attrs::MISMATCHED_TARGET_OS, - &attrs::UNKNOWN_CLIPPY_LINTS, &attrs::USELESS_ATTRIBUTE, &await_holding_invalid::AWAIT_HOLDING_LOCK, &await_holding_invalid::AWAIT_HOLDING_REFCELL_REF, @@ -1375,7 +1378,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&attrs::DEPRECATED_CFG_ATTR), LintId::of(&attrs::DEPRECATED_SEMVER), LintId::of(&attrs::MISMATCHED_TARGET_OS), - LintId::of(&attrs::UNKNOWN_CLIPPY_LINTS), LintId::of(&attrs::USELESS_ATTRIBUTE), LintId::of(&bit_mask::BAD_BIT_MASK), LintId::of(&bit_mask::INEFFECTIVE_BIT_MASK), @@ -1650,7 +1652,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS), LintId::of(&assign_ops::ASSIGN_OP_PATTERN), LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS), - LintId::of(&attrs::UNKNOWN_CLIPPY_LINTS), LintId::of(&blacklisted_name::BLACKLISTED_NAME), LintId::of(&blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS), LintId::of(&collapsible_if::COLLAPSIBLE_IF), diff --git a/src/tools/clippy/tests/ui/deprecated.rs b/src/tools/clippy/tests/ui/deprecated.rs index e1ee8dbca2c04..4a538021b98ea 100644 --- a/src/tools/clippy/tests/ui/deprecated.rs +++ b/src/tools/clippy/tests/ui/deprecated.rs @@ -9,5 +9,6 @@ #[warn(clippy::drop_bounds)] #[warn(clippy::temporary_cstring_as_ptr)] #[warn(clippy::panic_params)] +#[warn(clippy::unknown_clippy_lints)] fn main() {} diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr index edbb891afe07b..3429317498ed6 100644 --- a/src/tools/clippy/tests/ui/deprecated.stderr +++ b/src/tools/clippy/tests/ui/deprecated.stderr @@ -66,11 +66,17 @@ error: lint `clippy::panic_params` has been removed: `this lint has been uplifte LL | #[warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ +error: lint `clippy::unknown_clippy_lints` has been removed: `this lint has been integrated into the `unknown_lints` rustc lint` + --> $DIR/deprecated.rs:12:8 + | +LL | #[warn(clippy::unknown_clippy_lints)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: lint `clippy::unstable_as_slice` has been removed: ``Vec::as_slice` has been stabilized in 1.7` --> $DIR/deprecated.rs:1:8 | LL | #[warn(clippy::unstable_as_slice)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr index 1b859043bb53b..94a667e589891 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr @@ -1,52 +1,58 @@ -error: unknown clippy lint: clippy::if_not_els +error: unknown lint: `clippy::All` + --> $DIR/unknown_clippy_lints.rs:5:10 + | +LL | #![allow(clippy::All)] + | ^^^^^^^^^^^ help: did you mean: `clippy::all` + | + = note: `-D unknown-lints` implied by `-D warnings` + +error: unknown lint: `clippy::CMP_NAN` + --> $DIR/unknown_clippy_lints.rs:6:9 + | +LL | #![warn(clippy::CMP_NAN)] + | ^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_nan` + +error: unknown lint: `clippy::if_not_els` --> $DIR/unknown_clippy_lints.rs:9:8 | LL | #[warn(clippy::if_not_els)] | ^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::if_not_else` - | - = note: `-D clippy::unknown-clippy-lints` implied by `-D warnings` -error: unknown clippy lint: clippy::UNNecsaRy_cAst +error: unknown lint: `clippy::UNNecsaRy_cAst` --> $DIR/unknown_clippy_lints.rs:10:8 | LL | #[warn(clippy::UNNecsaRy_cAst)] | ^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unnecessary_cast` -error: unknown clippy lint: clippy::useles_transute +error: unknown lint: `clippy::useles_transute` --> $DIR/unknown_clippy_lints.rs:11:8 | LL | #[warn(clippy::useles_transute)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::useless_transmute` -error: unknown clippy lint: clippy::dead_cod +error: unknown lint: `clippy::dead_cod` --> $DIR/unknown_clippy_lints.rs:13:8 | LL | #[warn(clippy::dead_cod)] | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy` -error: unknown clippy lint: clippy::unused_colle +error: unknown lint: `clippy::unused_colle` --> $DIR/unknown_clippy_lints.rs:15:8 | LL | #[warn(clippy::unused_colle)] | ^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unused_self` -error: unknown clippy lint: clippy::const_static_lifetim +error: unknown lint: `clippy::const_static_lifetim` --> $DIR/unknown_clippy_lints.rs:17:8 | LL | #[warn(clippy::const_static_lifetim)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes` -error: unknown clippy lint: clippy::All +error: unknown lint: `clippy::All` --> $DIR/unknown_clippy_lints.rs:5:10 | LL | #![allow(clippy::All)] - | ^^^^^^^^^^^ help: lowercase the lint name: `clippy::all` - -error: unknown clippy lint: clippy::CMP_NAN - --> $DIR/unknown_clippy_lints.rs:6:9 - | -LL | #![warn(clippy::CMP_NAN)] - | ^^^^^^^^^^^^^^^ help: lowercase the lint name: `clippy::cmp_nan` + | ^^^^^^^^^^^ help: did you mean: `clippy::all` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors