From 469281c0dd6abb13b0b0067e0ed977e70145183c Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 28 Dec 2020 18:59:35 +0100 Subject: [PATCH 1/5] Check if never type feature is enabled by TyCtxt before suggesting empty enum lint --- clippy_lints/src/empty_enum.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index a249117d182f..585709660a4a 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -44,7 +44,9 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum { if let ItemKind::Enum(..) = item.kind { let ty = cx.tcx.type_of(did); let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); - if adt.variants.is_empty() { + + // Only suggest the never type if the feature is enabled + if adt.variants.is_empty() && cx.tcx.features().never_type { span_lint_and_help( cx, EMPTY_ENUM, From 83a458acf113a35ad9b50d5a4c7943ea5f5415ea Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 28 Dec 2020 20:18:27 +0100 Subject: [PATCH 2/5] Enable never type in empty enum ui test; run cargo dev bless --- tests/ui/empty_enum.rs | 3 ++- tests/ui/empty_enum.stderr | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ui/empty_enum.rs b/tests/ui/empty_enum.rs index 12428f29625c..a2e5c13c4528 100644 --- a/tests/ui/empty_enum.rs +++ b/tests/ui/empty_enum.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] #![warn(clippy::empty_enum)] - +// Enable never type to test empty enum lint +#![feature(never_type)] enum Empty {} fn main() {} diff --git a/tests/ui/empty_enum.stderr b/tests/ui/empty_enum.stderr index 466dfbe7cee7..7125e5f602b7 100644 --- a/tests/ui/empty_enum.stderr +++ b/tests/ui/empty_enum.stderr @@ -1,5 +1,5 @@ error: enum with no variants - --> $DIR/empty_enum.rs:4:1 + --> $DIR/empty_enum.rs:5:1 | LL | enum Empty {} | ^^^^^^^^^^^^^ From 275988cb73e5ad9e7628c7eb424be9cdcec57284 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 28 Dec 2020 20:44:21 +0100 Subject: [PATCH 3/5] Add additional lint doc to known problems section --- clippy_lints/src/empty_enum.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 585709660a4a..557a7c6ba98d 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -8,6 +8,10 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { /// **What it does:** Checks for `enum`s with no variants. /// + /// As of this writing, the never type is still a + /// nightly-only experimental API. Therefore, this lint is only triggered + /// if the never type is enabled + /// /// **Why is this bad?** If you want to introduce a type which /// can't be instantiated, you should use `!` (the never type), /// or a wrapper around it, because `!` has more extensive From bc97f5d2156e2fc42ff1a69ccbad9adb2b4568fb Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 4 Jan 2021 17:47:59 +0100 Subject: [PATCH 4/5] Address flip1995's review comments --- clippy_lints/src/empty_enum.rs | 15 +++++++++------ tests/ui/empty_enum_without_never_type.rs | 7 +++++++ 2 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 tests/ui/empty_enum_without_never_type.rs diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 557a7c6ba98d..4533d6447a77 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -8,12 +8,12 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { /// **What it does:** Checks for `enum`s with no variants. /// - /// As of this writing, the never type is still a + /// As of this writing, the `never_type` is still a /// nightly-only experimental API. Therefore, this lint is only triggered - /// if the never type is enabled + /// if the `never_type` is enabled. /// /// **Why is this bad?** If you want to introduce a type which - /// can't be instantiated, you should use `!` (the never type), + /// can't be instantiated, you should use `!` (the primitive type never), /// or a wrapper around it, because `!` has more extensive /// compiler support (type inference, etc...) and wrappers /// around it are the conventional way to define an uninhabited type. @@ -44,13 +44,16 @@ declare_lint_pass!(EmptyEnum => [EMPTY_ENUM]); impl<'tcx> LateLintPass<'tcx> for EmptyEnum { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { + // Only suggest the `never_type` if the feature is enabled + if !cx.tcx.features().never_type { + return; + } + let did = cx.tcx.hir().local_def_id(item.hir_id); if let ItemKind::Enum(..) = item.kind { let ty = cx.tcx.type_of(did); let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); - - // Only suggest the never type if the feature is enabled - if adt.variants.is_empty() && cx.tcx.features().never_type { + if adt.variants.is_empty() { span_lint_and_help( cx, EMPTY_ENUM, diff --git a/tests/ui/empty_enum_without_never_type.rs b/tests/ui/empty_enum_without_never_type.rs new file mode 100644 index 000000000000..4cbdfc47910f --- /dev/null +++ b/tests/ui/empty_enum_without_never_type.rs @@ -0,0 +1,7 @@ +#![allow(dead_code)] +#![warn(clippy::empty_enum)] + +// `never_type` is not enabled; this test has no stderr file +enum Empty {} + +fn main() {} \ No newline at end of file From a8d47b4b78a6e6a23dc3320ad3c9e6308f6d1934 Mon Sep 17 00:00:00 2001 From: nahuakang Date: Mon, 4 Jan 2021 18:41:42 +0100 Subject: [PATCH 5/5] Run cargo dev fmt --- clippy_lints/src/empty_enum.rs | 2 +- tests/ui/empty_enum_without_never_type.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 4533d6447a77..853b3afdc3ae 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -13,7 +13,7 @@ declare_clippy_lint! { /// if the `never_type` is enabled. /// /// **Why is this bad?** If you want to introduce a type which - /// can't be instantiated, you should use `!` (the primitive type never), + /// can't be instantiated, you should use `!` (the primitive type "never"), /// or a wrapper around it, because `!` has more extensive /// compiler support (type inference, etc...) and wrappers /// around it are the conventional way to define an uninhabited type. diff --git a/tests/ui/empty_enum_without_never_type.rs b/tests/ui/empty_enum_without_never_type.rs index 4cbdfc47910f..386677352e29 100644 --- a/tests/ui/empty_enum_without_never_type.rs +++ b/tests/ui/empty_enum_without_never_type.rs @@ -4,4 +4,4 @@ // `never_type` is not enabled; this test has no stderr file enum Empty {} -fn main() {} \ No newline at end of file +fn main() {}