negative_type_bound/
lib.rs

1#![feature(negative_impls, auto_traits)]
2
3/// **this crate uses feature negative_impls and auto_traits**
4///
5/// You may want to do something like
6/// ```ignore
7/// struct Foo<T>(T);
8///
9/// impl<T: From<U>, U> From<Foo<U>> for Foo<T> {
10///     fn from(v: Foo<U>) -> Self {
11///         Self(T::from(v.0))
12///     }
13/// }
14/// ```
15/// but it wont work because it conflicts with implementation `impl<T> From<T> for T {}`
16/// provided by `core`
17///
18/// so we have to bound `Foo<T> != Foo<U>`
19///
20/// this crate provides trait `NotEqual`
21///
22/// `(T, U): NotEqual` is equivalent to T != U
23///
24/// so this will work
25/// ```ignore
26/// struct Foo<T>(T);
27///
28/// impl<T: From<U>, U> From<Foo<U>> for Foo<T> where (Foo<T>, Foo<U>): NotEqual {
29///     fn from(v: Foo<U>) -> Self {
30///         Self(T::from(v.0))
31///     }
32/// }
33/// ```
34/// more simply...
35/// ```ignore
36/// struct Foo<T>(T);
37///
38/// impl<T: From<U>, U> From<Foo<U>> for Foo<T> where (T, U): NotEqual {
39///     fn from(v: Foo<U>) -> Self {
40///         Self(T::from(v.0))
41///     }
42/// }
43/// ```
44///
45/// this crate also provides `Equal`
46
47
48pub auto trait NotEqual {}
49
50impl<T> !NotEqual for (T, T) {}
51
52pub trait Equal {}
53
54impl<T> Equal for (T, T) {}
55
56#[cfg(test)]
57mod tests {
58    use crate::NotEqual;
59
60    #[test]
61    fn a() {
62        struct Foo<T>(T);
63
64        impl<T: From<U>, U> From<Foo<U>> for Foo<T> where (T, U): NotEqual {
65            fn from(v: Foo<U>) -> Self {
66                Self(T::from(v.0))
67            }
68        }
69    }
70}