# Conflicting implementations not overlapping

**URL:** <https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296>\
**Category:** Uncategorized\
**Created:** [May 8, 2020, 12:31am UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296 "2020-05-08T00:31:07Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tspiteri](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tspiteri/32/7283_2.png) [@tspiteri](https://internals.rust-lang.org/u/tspiteri)\
**Post date:** [May 8, 2020, 12:31am UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296/1 "2020-05-08T00:31:07Z")

</div>

```rust
pub trait Cond {
    type Output;
}
pub struct S;
impl<T> From<T> for S where T: Cond<Output = i32> {}
impl<T> From<T> for S where T: Cond<Output = u32> {}

```

The implementations cannot overlap, because `<T as Cond>::Output` cannot be both `i32` and `u32`. The code as far as I know does not use negative bounds which are problematic. That is because the second constraint isn't `T: !Cond<Output = i32>` or `T: Cond<Output != i32>`. Is there any reason I'm missing which would make accepting this a problem?

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [May 8, 2020, 1:49am UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296/2 "2020-05-08T01:49:31Z")

</div>

The workaround for this is a private trait

```rust
pub trait Cond {
    type Output;
}
pub struct S;

impl<T> From<T> for S where T: IntoS<T::Output> + Cond {
    fn from(value: T) -> Self { value.into_s() }
}

pub IntoS<C> {
    fn into_s(self) -> S;
}

impl<T: Cond<Output=u32>> IntoS<u32> for T {
    fn into_s(self) -> S { ... }
}

impl<T: Cond<Output=i32>> IntoS<i32> for T {
    fn into_s(self) -> S { ... }
}

```

But it would be nice if this workaround wasn't necessary.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [May 8, 2020, 3:49am UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296/3 "2020-05-08T03:49:47Z")

</div>

I believe this is [issue#20400](https://github.com/rust-lang/rust/issues/20400). [RFC#1672](https://github.com/rust-lang/rfcs/pull/1672) was proposed to fix this, but postponed for two main reasons. The first is that it's effectively blocked on chalk anyway, and the second is

> [@tspiteri](#):
>
> as far as I know does not use negative bounds which are problematic

that this isn't quite clear-cut, actually. As [boats writes](https://github.com/rust-lang/rfcs/pull/1672#issuecomment-262152934),

> [@withoutboats](#):
>
> I've realized this can express mutually exclusive traits and that it therefore carries all of the baggage associated with that feature.
> 
> ```rust
> // Two disjoint types
> struct Left;
> struct Right;
> 
> trait Exclusive {
> type Distinguisher;
> }
> 
> // Foo and Bar are mutually exclusive because their associated types are
> // disjoint.
> trait Foo: Exclusive<Distinguisher = Left> { }
> trait Bar: Exclusive<Distinguisher = Right> { }
> 
> trait Baz { }
> 
> // These impls are recognized as non-overlapping because the type parameters
> // implement two exclusive forms of the same trait
> impl<T: Foo> Baz for T { }
> impl<T: Bar> Baz for T { }
> 
> ```

---

<div class="post-metadata">

**Author:** ![tspiteri](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tspiteri/32/7283_2.png) [@tspiteri](https://internals.rust-lang.org/u/tspiteri)\
**Post date:** [May 8, 2020, 2:23pm UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296/4 "2020-05-08T14:23:56Z")

</div>

Thanks for the workaround. Though in my case what I really wanted was `From` for the first condition and `TryFrom` for the second; so I created another trait instead of using `TryFrom`.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [August 6, 2020, 2:23pm UTC](https://internals.rust-lang.org/t/conflicting-implementations-not-overlapping/12296/5 "2020-08-06T14:23:58Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
