Open
Description
Consider the following code:
#![feature(auto_traits)]
#![feature(negative_impls)]
use core::any::TypeId;
auto trait NotSame {}
impl<T> ! NotSame for (T, T) {}
#[derive(Debug)]
pub struct EventData {
pub id: TypeId,
payload: Box<dyn std::any::Any>,
}
impl EventData {
pub fn new<T: 'static>(payload: T) -> Self {
let id = TypeId::of::<T>();
let payload = Box::new(payload);
Self { id, payload }
}
}
impl<T: 'static> From<T> for EventData
where (T, EventData): NotSame
{
fn from(t: T) -> Self {
Self::new(t)
}
}
fn main() {
let v: EventData = ().into();
}
It does not compile:
error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `(dyn Any + 'static): NotSame` is not satisfied in `((), EventData)`
--> src/main.rs:34:24
|
34 | let v: EventData = ().into();
| ^^ ---- required by a bound introduced by this call
| |
| within `((), EventData)`, the trait `NotSame` is not implemented for `(dyn Any + 'static)`
|
= note: required because it appears within the type `PhantomData<(dyn Any + 'static)>`
= note: required because it appears within the type `Unique<(dyn Any + 'static)>`
= note: required because it appears within the type `Box<(dyn Any + 'static)>`
note: required because it appears within the type `EventData`
However, if we remove the field containing std::any::Any
, it compiles fine:
#![feature(auto_traits)]
#![feature(negative_impls)]
use core::any::TypeId;
auto trait NotSame {}
impl<T> ! NotSame for (T, T) {}
#[derive(Debug)]
pub struct EventData {
}
impl EventData {
pub fn new<T: 'static>(payload: T) -> Self {
Self {}
}
}
impl<T: 'static> From<T> for EventData
where (T, EventData): NotSame
{
fn from(t: T) -> Self {
Self::new(t)
}
}
fn main() {
let v: EventData = ().into();
}
Another strange thing is that if we change ().into()
to EventData::from(())
, then none of these codes compiles.
Please note that no types were changed. Click here to see live demo