about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-11 17:12:14 +0000
committerbors <bors@rust-lang.org>2021-10-11 17:12:14 +0000
commit5b210643ebf2485aafdf2494de8cf41941a64e95 (patch)
tree60ecf0b4cd6f526c9e5d02474b2c7e82ac233760 /src/test/ui
parent1067e2ca5e9cfe5c79f956e49ffc684c5142d49b (diff)
parentf4836768be12a0cd3a6bd8afc551ae836a87d973 (diff)
downloadrust-5b210643ebf2485aafdf2494de8cf41941a64e95.tar.gz
rust-5b210643ebf2485aafdf2494de8cf41941a64e95.zip
Auto merge of #83908 - Flying-Toast:master, r=davidtwco
Add enum_intrinsics_non_enums lint

There is a clippy lint to prevent calling [`mem::discriminant`](https://doc.rust-lang.org/std/mem/fn.discriminant.html) with a non-enum type. I think the lint is worthy of being included in rustc, given that `discriminant::<T>()` where `T` is a non-enum has an unspecified return value, and there are no valid use cases where you'd actually want this.

I've also made the lint check [variant_count](https://doc.rust-lang.org/core/mem/fn.variant_count.html) (#73662).

closes #83899
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/consts/const-variant-count.rs2
-rw-r--r--src/test/ui/enum-discriminant/discriminant_value-wrapper.rs3
-rw-r--r--src/test/ui/lint/lint-enum-intrinsics-non-enums.rs67
-rw-r--r--src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr95
4 files changed, 166 insertions, 1 deletions
diff --git a/src/test/ui/consts/const-variant-count.rs b/src/test/ui/consts/const-variant-count.rs
index 455419d2c7f..50eaeeb4685 100644
--- a/src/test/ui/consts/const-variant-count.rs
+++ b/src/test/ui/consts/const-variant-count.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![allow(dead_code)]
+#![allow(dead_code, enum_intrinsics_non_enums)]
 #![feature(variant_count)]
 #![feature(never_type)]
 
diff --git a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
index daef2de87a9..65dc9166330 100644
--- a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(enum_intrinsics_non_enums)]
+
 use std::mem;
 
 enum ADT {
diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs b/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs
new file mode 100644
index 00000000000..8ad337064e5
--- /dev/null
+++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs
@@ -0,0 +1,67 @@
+// Test the enum_intrinsics_non_enums lint.
+
+#![feature(variant_count)]
+
+use std::mem::{discriminant, variant_count};
+
+enum SomeEnum {
+    A,
+    B,
+}
+
+struct SomeStruct;
+
+fn generic_discriminant<T>(v: &T) {
+    discriminant::<T>(v);
+}
+
+fn generic_variant_count<T>() -> usize {
+    variant_count::<T>()
+}
+
+fn test_discriminant() {
+    discriminant(&SomeEnum::A);
+    generic_discriminant(&SomeEnum::B);
+
+    discriminant(&());
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&&SomeEnum::B);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&SomeStruct);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&123u32);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&&123i8);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+}
+
+fn test_variant_count() {
+    variant_count::<SomeEnum>();
+    generic_variant_count::<SomeEnum>();
+
+    variant_count::<&str>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<*const u8>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<()>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<&SomeEnum>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+}
+
+fn main() {
+    test_discriminant();
+    test_variant_count();
+
+    // The lint ignores cases where the type is generic, so these should be
+    // allowed even though their return values are unspecified
+    generic_variant_count::<SomeStruct>();
+    generic_discriminant::<SomeStruct>(&SomeStruct);
+}
diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
new file mode 100644
index 00000000000..bec9fb62efa
--- /dev/null
+++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
@@ -0,0 +1,95 @@
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:26:5
+   |
+LL |     discriminant(&());
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(enum_intrinsics_non_enums)]` on by default
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `()`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:26:18
+   |
+LL |     discriminant(&());
+   |                  ^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:29:5
+   |
+LL |     discriminant(&&SomeEnum::B);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&SomeEnum`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:29:18
+   |
+LL |     discriminant(&&SomeEnum::B);
+   |                  ^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:32:5
+   |
+LL |     discriminant(&SomeStruct);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `SomeStruct`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:32:18
+   |
+LL |     discriminant(&SomeStruct);
+   |                  ^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:35:5
+   |
+LL |     discriminant(&123u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `u32`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:35:18
+   |
+LL |     discriminant(&123u32);
+   |                  ^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:38:5
+   |
+LL |     discriminant(&&123i8);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&i8`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:38:18
+   |
+LL |     discriminant(&&123i8);
+   |                  ^^^^^^^
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:46:5
+   |
+LL |     variant_count::<&str>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&str`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:49:5
+   |
+LL |     variant_count::<*const u8>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `*const u8`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:52:5
+   |
+LL |     variant_count::<()>();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `()`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:55:5
+   |
+LL |     variant_count::<&SomeEnum>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&SomeEnum`, which is not an enum.
+
+error: aborting due to 9 previous errors
+