diff options
| -rw-r--r-- | tests/ui/type_id_on_box.fixed | 42 | ||||
| -rw-r--r-- | tests/ui/type_id_on_box.rs | 42 | ||||
| -rw-r--r-- | tests/ui/type_id_on_box.stderr | 20 | ||||
| -rw-r--r-- | tests/ui/type_id_on_box_unfixable.rs | 31 | ||||
| -rw-r--r-- | tests/ui/type_id_on_box_unfixable.stderr | 22 |
5 files changed, 99 insertions, 58 deletions
diff --git a/tests/ui/type_id_on_box.fixed b/tests/ui/type_id_on_box.fixed index bdc45a93e71..3656043700f 100644 --- a/tests/ui/type_id_on_box.fixed +++ b/tests/ui/type_id_on_box.fixed @@ -22,41 +22,35 @@ fn existential() -> impl Any { trait AnySubTrait: Any {} impl<T: Any> AnySubTrait for T {} -// `Any` is an indirect supertrait -trait AnySubSubTrait: AnySubTrait {} -impl<T: AnySubTrait> AnySubSubTrait for T {} - -// This trait mentions `Any` in its predicates, but it is not a subtrait of `Any`. -trait NormalTrait -where - i32: Any, -{ -} -impl<T> NormalTrait for T {} - fn main() { + // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing + let ref_dyn: &dyn Any = &42; + let _ = ref_dyn.type_id(); + let any_box: Box<dyn Any> = Box::new(0usize); let _ = (*any_box).type_id(); - let _ = TypeId::of::<Box<dyn Any>>(); // Don't lint. We explicitly say "do this instead" if this is intentional + //~^ ERROR: calling `.type_id()` on + + // Don't lint. We explicitly say "do this instead" if this is intentional + let _ = TypeId::of::<Box<dyn Any>>(); let _ = (*any_box).type_id(); + + // 2 derefs are needed here to get to the `dyn Any` let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>); - let _ = (**any_box).type_id(); // 2 derefs are needed here to get to the `dyn Any` + let _ = (**any_box).type_id(); + //~^ ERROR: calling `.type_id()` on let b = existential(); - let _ = b.type_id(); // Don't lint. + let _ = b.type_id(); // Don't + + let b: Box<dyn AnySubTrait> = Box::new(1); + let _ = (*b).type_id(); + //~^ ERROR: calling `.type_id()` on let b: SomeBox = Box::new(0usize); let _ = (*b).type_id(); + //~^ ERROR: calling `.type_id()` on let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`! - - let b: Box<dyn AnySubTrait> = Box::new(1); - let _ = (*b).type_id(); // Lint if calling `type_id` on a `dyn Trait` where `Trait: Any` - - let b: Box<dyn AnySubSubTrait> = Box::new(1); - let _ = b.type_id(); // Known FN - Any is not an "immediate" supertrait - - let b: Box<dyn NormalTrait> = Box::new(1); - let _ = b.type_id(); // `NormalTrait` does not have `Any` as its supertrait (even though it mentions it in `i32: Any`) } diff --git a/tests/ui/type_id_on_box.rs b/tests/ui/type_id_on_box.rs index e087d9989d8..4bd9e73f2da 100644 --- a/tests/ui/type_id_on_box.rs +++ b/tests/ui/type_id_on_box.rs @@ -22,41 +22,35 @@ fn existential() -> impl Any { trait AnySubTrait: Any {} impl<T: Any> AnySubTrait for T {} -// `Any` is an indirect supertrait -trait AnySubSubTrait: AnySubTrait {} -impl<T: AnySubTrait> AnySubSubTrait for T {} - -// This trait mentions `Any` in its predicates, but it is not a subtrait of `Any`. -trait NormalTrait -where - i32: Any, -{ -} -impl<T> NormalTrait for T {} - fn main() { + // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing + let ref_dyn: &dyn Any = &42; + let _ = ref_dyn.type_id(); + let any_box: Box<dyn Any> = Box::new(0usize); let _ = any_box.type_id(); - let _ = TypeId::of::<Box<dyn Any>>(); // Don't lint. We explicitly say "do this instead" if this is intentional + //~^ ERROR: calling `.type_id()` on + + // Don't lint. We explicitly say "do this instead" if this is intentional + let _ = TypeId::of::<Box<dyn Any>>(); let _ = (*any_box).type_id(); + + // 2 derefs are needed here to get to the `dyn Any` let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>); - let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any` + let _ = any_box.type_id(); + //~^ ERROR: calling `.type_id()` on let b = existential(); - let _ = b.type_id(); // Don't lint. + let _ = b.type_id(); // Don't + + let b: Box<dyn AnySubTrait> = Box::new(1); + let _ = b.type_id(); + //~^ ERROR: calling `.type_id()` on let b: SomeBox = Box::new(0usize); let _ = b.type_id(); + //~^ ERROR: calling `.type_id()` on let b = BadBox(Box::new(0usize)); let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`! - - let b: Box<dyn AnySubTrait> = Box::new(1); - let _ = b.type_id(); // Lint if calling `type_id` on a `dyn Trait` where `Trait: Any` - - let b: Box<dyn AnySubSubTrait> = Box::new(1); - let _ = b.type_id(); // Known FN - Any is not an "immediate" supertrait - - let b: Box<dyn NormalTrait> = Box::new(1); - let _ = b.type_id(); // `NormalTrait` does not have `Any` as its supertrait (even though it mentions it in `i32: Any`) } diff --git a/tests/ui/type_id_on_box.stderr b/tests/ui/type_id_on_box.stderr index 8edecc47c74..4528195607d 100644 --- a/tests/ui/type_id_on_box.stderr +++ b/tests/ui/type_id_on_box.stderr @@ -1,5 +1,5 @@ error: calling `.type_id()` on `Box<dyn Any>` - --> tests/ui/type_id_on_box.rs:39:13 + --> tests/ui/type_id_on_box.rs:31:13 | LL | let _ = any_box.type_id(); | -------^^^^^^^^^^ @@ -12,9 +12,9 @@ LL | let _ = any_box.type_id(); = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` error: calling `.type_id()` on `Box<dyn Any>` - --> tests/ui/type_id_on_box.rs:43:13 + --> tests/ui/type_id_on_box.rs:40:13 | -LL | let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any` +LL | let _ = any_box.type_id(); | -------^^^^^^^^^^ | | | help: consider dereferencing first: `(**any_box)` @@ -22,8 +22,8 @@ LL | let _ = any_box.type_id(); // 2 derefs are needed here to get to the `d = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear -error: calling `.type_id()` on `Box<dyn Any>` - --> tests/ui/type_id_on_box.rs:49:13 +error: calling `.type_id()` on `Box<dyn AnySubTrait>` + --> tests/ui/type_id_on_box.rs:47:13 | LL | let _ = b.type_id(); | -^^^^^^^^^^ @@ -31,18 +31,18 @@ LL | let _ = b.type_id(); | help: consider dereferencing first: `(*b)` | = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want - = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear + = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubTrait>>()` instead, which makes it more clear -error: calling `.type_id()` on `Box<dyn AnySubTrait>` - --> tests/ui/type_id_on_box.rs:55:13 +error: calling `.type_id()` on `Box<dyn Any>` + --> tests/ui/type_id_on_box.rs:51:13 | -LL | let _ = b.type_id(); // Lint if calling `type_id` on a `dyn Trait` where `Trait: Any` +LL | let _ = b.type_id(); | -^^^^^^^^^^ | | | help: consider dereferencing first: `(*b)` | = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want - = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubTrait>>()` instead, which makes it more clear + = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear error: aborting due to 4 previous errors diff --git a/tests/ui/type_id_on_box_unfixable.rs b/tests/ui/type_id_on_box_unfixable.rs new file mode 100644 index 00000000000..f6d09834adb --- /dev/null +++ b/tests/ui/type_id_on_box_unfixable.rs @@ -0,0 +1,31 @@ +#![warn(clippy::type_id_on_box)] + +use std::any::{Any, TypeId}; +use std::ops::Deref; + +trait AnySubTrait: Any {} +impl<T: Any> AnySubTrait for T {} + +// `Any` is an indirect supertrait +trait AnySubSubTrait: AnySubTrait {} +impl<T: AnySubTrait> AnySubSubTrait for T {} + +// This trait mentions `Any` in its predicates, but it is not a subtrait of `Any`. +trait NormalTrait +where + i32: Any, +{ +} +impl<T> NormalTrait for T {} + +fn main() { + // (currently we don't look deeper than one level into the supertrait hierachy, but we probably + // could) + let b: Box<dyn AnySubSubTrait> = Box::new(1); + let _ = b.type_id(); + //~^ ERROR: calling `.type_id()` on + + let b: Box<dyn NormalTrait> = Box::new(1); + let _ = b.type_id(); + //~^ ERROR: calling `.type_id()` on +} diff --git a/tests/ui/type_id_on_box_unfixable.stderr b/tests/ui/type_id_on_box_unfixable.stderr new file mode 100644 index 00000000000..539ed481ec1 --- /dev/null +++ b/tests/ui/type_id_on_box_unfixable.stderr @@ -0,0 +1,22 @@ +error: calling `.type_id()` on `Box<dyn AnySubSubTrait>` + --> tests/ui/type_id_on_box_unfixable.rs:25:13 + | +LL | let _ = b.type_id(); + | ^^^^^^^^^^^ + | + = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want + = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubSubTrait>>()` instead, which makes it more clear + = note: `-D clippy::type-id-on-box` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]` + +error: calling `.type_id()` on `Box<dyn NormalTrait>` + --> tests/ui/type_id_on_box_unfixable.rs:29:13 + | +LL | let _ = b.type_id(); + | ^^^^^^^^^^^ + | + = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want + = note: if this is intentional, use `TypeId::of::<Box<dyn NormalTrait>>()` instead, which makes it more clear + +error: aborting due to 2 previous errors + |
