# Language inconsistency when implementing a trait

**URL:** <https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878>\
**Category:** language design\
**Created:** [February 22, 2020, 2:25pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878 "2020-02-22T14:25:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 22, 2020, 2:25pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/1 "2020-02-22T14:25:15Z")

</div>

I'm escalating [this](https://users.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/38562) from [users.rust-lang.org](http://users.rust-lang.org) because the weirdness just keeps rising.

Basically the issue is that this is accepted:

```rust
impl<T> TryFrom<RcBar<T>> for Rc<T> { 
    // code here
}

impl<T> TryFrom<Rc<T>> for RcBar<T> {
    // code here
}

```

whereas this is not:

```rust
impl<T> TryFrom<BoxBar<T>> for Box<T> { 
    // code here
}

impl<T> TryFrom<Box<T>> for BoxBar<T> {
    // code here
}

```

In the above snippets, `RcBar<T>` and `BoxBar<T>` are local types, yet the impls `for RcBar<T>` and `for BoxBar<T>` are rejected regardless. So the RFC doesn't even make any sense there.

Urlo user @trentj [pointed me](https://users.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/38562/2) to the `#[fundamental]` attribute as well as [RFC 1023](https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md), but that doesn't really help me forward. In fact all it does is tell me that `#[fundamental]` makes `Box<T>` behave very differently from `Rc<T>` and `Arc<T>` in a very important respect, but fails to explain why I should care as a user other than some hand-wavey mentions of safety and coherence. Which I'd be willing to believe in principle, except that it's:

1. apparently not needed for `Rc<T>` and `Arc<T>` so it's not consistent (instead a choice was made to make it consistent with `&T` and `&mut T` for whatever reason) and
2. actively harming my ability to get useful work done because of the unexpected inconsistency.

From the RFC:

```rust
This RFC proposes a shift that attempts to strike a balance between the needs of downstream and upstream crates. In particular, we wish to preserve the ability of upstream crates to add impls to traits that they define, while still allowing downstream creates to define the sorts of impls they need.

```

I don't know if I can call this "mission failed", but it's definitely no success because so far I haven't been able to write the impl blocks I need to for `Box<T>`, and it seems that that is directly due to the implementation of this RFC.

Can anyone tell me what I need to do to write the impl blocks I need to and get around the `#[fundamental]` stumbling block?

(I'm silently hoping that the answer isn't the forever-nightly-feature called impl specialization...)

---

<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:** [February 22, 2020, 5:18pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/2 "2020-02-22T17:18:06Z")

</div>

I think [re-rebalancing coherence (RFC#2451)](https://github.com/rust-lang/rfcs/pull/2451) is partially to blame here for the inconsistency. Going back to 1.34.0, when `TryFrom` was stabilized and re-rebalancing coherence was not yet in, I get a different set of errors that also disallows the impl on `Rc`:

```rust
use std::rc::Rc;
use std::convert::TryFrom;

struct MyRc<T>(Rc<T>);
struct MyBox<T>(Box<T>);

impl<T> TryFrom<MyRc<T>> for Rc<T> {}
impl<T> TryFrom<Rc<T>> for MyRc<T> {}

impl<T> TryFrom<MyBox<T>> for Box<T> {}
impl<T> TryFrom<Box<T>> for MyBox<T> {}

```

### 1.41.0 (re-rebalancing coherence)

```rust
error[E0119]: conflicting implementations of trait `std::convert::TryFrom<MyBox<_>>` for type `std::boxed::Box<_>`:
  --> src/lib.rs:10:1
   |
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::TryFrom<U> for T
             where U: std::convert::Into<T>;
   = note: downstream crates may implement trait `std::convert::From<MyBox<_>>` for type `std::boxed::Box<_>`

error[E0119]: conflicting implementations of trait `std::convert::TryFrom<std::boxed::Box<_>>` for type `MyBox<_>`:
  --> src/lib.rs:11:1
   |
11 | impl<T> TryFrom<Box<T>> for MyBox<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::TryFrom<U> for T
             where U: std::convert::Into<T>;
   = note: downstream crates may implement trait `std::convert::From<std::boxed::Box<_>>` for type `MyBox<_>`

error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`MyBox<T>`)
  --> src/lib.rs:10:6
   |
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
   | ^ type parameter `T` must be covered by another type when it appears before the first local type (`MyBox<T>`)
   |
   = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type
   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last

```

### 1.34.0 (pre-re-rebalancing coherence)

```rust
error: conflicting implementations of trait `std::convert::TryFrom<MyBox<_>>` for type `std::boxed::Box<_>`: (E0119)
  --> src\main.rs:10:1
   |
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: #[deny(incoherent_fundamental_impls)] on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::TryFrom<U> for T
             where U: std::convert::Into<T>;
   = note: downstream crates may implement trait `std::convert::From<MyBox<_>>` for type `std::boxed::Box<_>`

error: conflicting implementations of trait `std::convert::TryFrom<std::boxed::Box<_>>` for type `MyBox<_>`: (E0119)
  --> src\main.rs:11:1
   |
11 | impl<T> TryFrom<Box<T>> for MyBox<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
   = note: conflicting implementation in crate `core`:
           - impl<T, U> std::convert::TryFrom<U> for T
             where U: std::convert::Into<T>;
   = note: downstream crates may implement trait `std::convert::From<std::boxed::Box<_>>` for type `MyBox<_>`

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
 --> src\main.rs:7:1
  |
7 | impl<T> TryFrom<MyRc<T>> for Rc<T> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
  |
  = note: only traits defined in the current crate can be implemented for a type parameter

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
  --> src\main.rs:10:1
   |
10 | impl<T> TryFrom<MyBox<T>> for Box<T> {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
   |
   = note: only traits defined in the current crate can be implemented for a type parameter

```

Ooh, further tidbit: the `Box` impl used to be allowed, and was deprecated/removed with [#46205](https://github.com/rust-lang/rust/issues/46205). That issue contains some further information about why this is incoherent.

So two takeaway points: under rebalancing coherence, both of these cases are disallowed; re-rebalancing coherence allows it for non-fundamental (covering) types. And specialization doesn't even help you at all.

* * *

`#[fundamental]` is inherently about negative reasoning. A `#[fundamental]` trait can be assumed to not be implemented (e.g. `Fn*` and `Sized`) if it is not currently implemented. A `#[fundamental]` _type_ is slightly different; per my reading of re-rebalancing coherence, a fundamental type's only quality is that its locality is always that of its (singular) type argument, and as such cannot "cover" a type variable.

Without knowing the exact use case of your `BoxBar`, it's not really possible to suggest other paths. My only suggestion would really be to, if at all possible, use `Box<Bar<T>>` (where `Bar` is a `repr(transparent)` wrapper) rather than a custom box type.

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [February 22, 2020, 5:36pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/3 "2020-02-22T17:36:31Z")

</div>

I initially didn't understand what `#[fundamental]` meant and like many things in Rust, grasping the concept and its implications (and justifications) was... difficult (Rust has so much jargon, some of which is newly invented and some of which is academic [PLT](https://en.wikipedia.org/wiki/Programming_language_theory) stuff that's way over my head). Anyway, I found [this Q&A on StackOverflow](https://stackoverflow.com/questions/59022263/what-is-a-fundamental-type-in-rust) to be enlightening and it might help you understand, @jjpe, why certain `impl`s involving `Box<T>` aren't permitted.

I think the compiler's error messages could be clarified with a link to something that explains fundamental types and why/how they're special (in a beginner-friendly way).

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [February 22, 2020, 7:11pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/4 "2020-02-22T19:11:55Z")

</div>

I think part of the issue is that, if I'm reading between the lines correctly, `#[fundamental]` was originally introduced as a sort of tentative "we need to circle back to this later" kind of solution, in the hopes something better would come later:

> This attribute is unstable because it is not clear whether it will prove to be adequate or need to be generalized; this part of the design can be considered somewhat incomplete, and we expect to finalize it based on what we observe after the 1.0 release.
> 
> [RFC 1023 Rebalancing Coherence](https://github.com/nox/rust-rfcs/blob/master/text/1023-rebalancing-coherence.md)

But at this point it seems unlikely we'll get rid of it, and extremely unlikely we'll ever end up on a radically different mechanism, so we probably should commit to doing a proper bikeshed on this terminology and improving some of the error messages and documentation (e.g. the `Box` docs don't even mention that it's `#[fundamental]`).

Might as well start here. I can't think of anything I actually feel good about, but just as a strawman to get the ball rolling: how does `#[no_new_blanket_impls]` for types and `#[no_new_impls_for_existing_types]` for traits sound?

---

<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:** [February 22, 2020, 8:03pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/5 "2020-02-22T20:03:40Z")

</div>

Honestly, fundamental is a good descriptor of _why_ the traits/types are like they are, rather than what the actual impact is. We just need to actually better document and expose the fundamental nature and what impact that has on coherence.

And perhaps, if we embrace the fundamental terminology, we should move towards marking the other primitive types (`*[const|mut] _`, tuples, `[_]`, `[_; N]`, and `fn` pointers) as fundamental. After all, these _are_ fundamental builtin types to the language, not "just" another struct definition in `core`/`std`. This would, of course, require finalizing and committing to the exact set of `core`/`std` traits that any fundamental types implement, so is more of a "making fundamental consistent" long term goal than a PR to make soon.

Referencing the re-rebalancing coherence RFC is probably the better RFC to reference than rebalancing coherence, as it redefines and respecifies the entirety of coherence to be more consistent, especially where #1023 and #1105 contradict each other.

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [February 22, 2020, 8:30pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/6 "2020-02-22T20:30:53Z")

</div>

> [@CAD97](#):
>
> Honestly, fundamental is a good descriptor of _why_ the traits/types are like they are, rather than what the actual impact is.

I disagree that "fundamental is a good descriptor". I had exactly zero clue what "fundamental type" meant or why it had any impact on traits/impls. Even after reading that StackOverflow Q&A I previously linked to, I still don't really see why "fundamental" is a good descriptor.

Naming things is hard. I don't have any better suggestions. But I would like to better understand _why_ you think fundamental is a good descriptor, because I think you have a perspective or insight that I lack.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 22, 2020, 9:00pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/7 "2020-02-22T21:00:09Z")

</div>

Just to circle back for a second to the issue that got the ball rolling. How do I implement `TryFrom` for `Box<T>`? The blanket impl defined in the stdlib is not acceptable to rustc, so I need something better.

Here's some context, as I plan to open source the crate once it's actually usable anyway: I'm writing a derive macro that computes deltas between instances of a certain type. These deltas are de/serializable using Serde. The deltas are computed and applied to types by means of a trait called DeltaOps, and that trait has an associated type representing the Delta for the implementing type. Here's the thing, I need TryFrom to convert the Delta types each way ie one TryFrom impl to go from implementing type to the corresponding Delta type, and one to convert back. The conversion from Delta to the implementing type can fail and I need to conversions to be symmetric, so both directions implement TryFrom rather than From.

This seems to become an issue with `Box<T>` because of the fundamental attribute. So. How do I kick these intentional but undesirable side-effects out of the equation?

---

<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:** [February 22, 2020, 10:43pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/8 "2020-02-22T22:43:03Z")

</div>

> [@jjpe](#):
>
> How do I implement `TryFrom` for `Box<T>` ?

The answer seems to be you don't. It's in violation of re-rebalancing coherence, because `Box<T>` is an uncovered type parameter; it's not an upstream type, it's not a local type: it's potentially a _downstream_ type, local to a downstream crate. You need to somehow cover the type parameter (if it needs to exist) with a local type.

> [@jjpe](#):
>
> context

Just to sketch out the APIs you're trying to provide, to understand what you're trying to do,

```rust
trait DeltaOps {
    type Delta: Serialize + Deserialize + TryFrom<Self> + TryInto<Self>;
    fn delta(left: &Self, right: &Self) -> Self::Delta;
}

```

...and then your example over on urlo has `struct BoxDelta<T>(<T as DeltaOps>::Delta)` for... some reason?

Given that your example impls for `Box`/`Rc` are just "clone out the value, use it's `TryInto`", I'd just leave it to the user to clone out the value, honestly.

The one reason I can see to want a `Delta` type is to make naming an otherwise unnamable type more easily namable. But [a type alias handles this fine](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=993bc09c14002b899e8a17c304216c3b):

```rust
trait DeltaOps {
    type Delta;
    fn delta(left: &Self, right: &Self) -> Self::Delta;
}

type Delta<T: DeltaOps> = <T as DeltaOps>::Delta;

impl DeltaOps for usize {
    type Delta = isize;
    fn delta(left: &Self, right: &Self) -> isize {
        right.wrapping_sub(*left) as isize
    }
}

fn main() {
    let x: Delta<usize> = DeltaOps::delta(&0, &10);
    dbg!(x);
}

```

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 23, 2020, 3:09pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/9 "2020-02-23T15:09:16Z")

</div>

> [@CAD97](#):
>
> ...and then your example over on urlo has `struct BoxDelta<T>(<T as DeltaOps>::Delta)` for... some reason?

The idea is that if `MyType` is the type for which a `DeltaOps` impl is being written / generated, then`<MyType as DeltaOps>::Delta` is the type representing the Delta for `MyType`. Thus, instances of `<MyType as DeltaOps>::Delta` represent individual delta's between instances of `MyType`. This delta type is generated by the derive macro, and thus both its name and structure are known at that time, but it is useful to be able to talk generically about delta types (e.g. in the return type of the `DeltaOps::delta()` method, or in the reverse operation not shown here, `fn apply_delta(&self, &Self::Delta) -> Self`), hence the associated type. The associated type is also not the issue here, it's working as it's supposed to. So I'm not sure why you're focusing on that. The issue is the `TryFrom<T>` impls, and specifically for `Box<T>` although now I should probably stretch that up to "types marked as `#[fundamental]`".

> [@CAD97](#):
>
> Given that your example impls for `Box` / `Rc` are just "clone out the value, use it's `TryInto` ", I'd just leave it to the user to clone out the value, honestly.

The entire point of the derive is for the declaration to consist of a one-liner on top of a type: `#[derive(Delta)]`. Keep in mind that if a user need to do manual work, then for complex types (i.e. many layers of composition deep) it can be that in order to use this derive macro they'd suddenly need to implement a bunch of traits for a bunch of types. So no, asking the user to do a lot of the work to support deltas is not a workable solution, just like it wouldn't be okay to ask a user to manually write a `Deserialize` impl for a dumb data object (i.e. no special behavior of any kind - just pure data representation).

The `TryFrom<T>` impls should either be present with the rest of the infrastructure (i.e. where the `DeltaOps` trait is defined - this is mainly for types defined in stdlib, e.g. `Rc<T>` or `Box<T>`) or generated by the derive macro (i.e. to convert between a type that is generated, which is a delta type, and the original type that the delta type is based on). In either case the user shouldn't have to write anything except their type and the 1-liner containing the call to the derive macro.

This `#[fundamental]` business has taken away a valuable piece of functionality, and TBH I want it back rather than resort to nasty kludges.

---

<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:** [February 23, 2020, 3:19pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/10 "2020-02-23T15:19:25Z")

</div>

What I'm missing is _why_ you need to implement `TryFrom` in the first place, or rather, why you have your "`BoxBar`" type that you want/need to be `TryFrom`/`Into` `Box` genetically.

The reason I ask about the associated type is that the only use you've given for "`BoxBar`" is "`struct BoxBar<T: FooOps>(T::Bar);`".

On top of that, a conversion that would be as well sold to be from `T` or `&T` as `Box<T>`.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 23, 2020, 3:29pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/11 "2020-02-23T15:29:39Z")

</div>

> [@CAD97](#):
>
> What I'm missing is _why_ you need to implement `TryFrom` in the first place, or rather, why you have your " `BoxBar` " type that you want/need to be `TryFrom` / `Into` `Box` genetically.

The `TryFrom` impls exist because the delta types exist, and it must be possible to interconvert (in a controlled way) between a value of a type and a value of its corresponding delta type. It's a very useful building block in generating deltas, while making sure those delta's are de/serializable.

The de/serialization is one reason that delta's need to have their own actual type.

> [@CAD97](#):
>
> The reason I ask about the associated type is that the only use you've given for " `BoxBar` " is " `struct BoxBar<T: FooOps>(T::Bar);` ".

That's easy, that code only exists to enable types that internally use `Box<T>` to use `#[derive(Delta)]`. The data flow can go both ways so it must be possible to create a new Box from a BoxDelta.

References aren't supported since it's fundamentally impossible to instantiate a completely new borrow without first having something to borrow from. Nobody that understands deltas as well as view structs would even try this, because it makes about as much sense as trying to add the string "blah" to the number 1.

---

<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:** [February 23, 2020, 3:37pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/12 "2020-02-23T15:37:25Z")

</div>

> [@jjpe](#):
>
> That's easy, that code only exists to enable types that internally use `Box<T>` to use `#[derive(Delta)]` .

Can you not just `impl<D: DeltaOps> DeltaOps for Box<D>` in the crate defining `DeltaOps` and use `Box` everywhere?

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 23, 2020, 3:42pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/13 "2020-02-23T15:42:16Z")

</div>

The impl you refer to exists as well. It's required but not sufficient.

But in the meantime I think I have a workable solution: Ditch `TryFrom` in favor of a trait that effectively does the same thing, let's call it `Convert`, that is not part of stdlib. The idea is that since `Convert` isn't tainted by `#[fundamental]` semantics, I can do whatever I want with it.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [February 24, 2020, 1:00am UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/14 "2020-02-24T01:00:25Z")

</div>

Notwithstanding `#[fundamental]`, this would be a good use case for negative trait impls. The error message correctly notes that a downstream crate could add an impl like

```rust
impl From<Box<Foo>> for MyBox<Foo>

```

where `Foo` is a type defined by that crate. That would then trigger the standard library's `impl<T, U> Into<U> for T where U: From<T>`, which would in turn trigger the standard library's `impl<U, T> TryFrom<T> for U where T: Into<U>`, conflicting with your impl.

If you could prevent downstream crates from doing that by writing:

```rust
impl<T> !From<Box<A>> for MyBox<B> {}

```

then in theory the compiler could allow your `TryFrom` impl.

As it happens, [there's an active rustc PR](https://github.com/rust-lang/rust/pull/68004) to allow negative impls for arbitrary traits. The PR as it stands does not affect coherence – the coherence check would simply ignore negative impls – but [@nikomatsakis has said](https://github.com/rust-lang/rust/pull/68004#issuecomment-572048782) that's a future goal.

Note that even after this feature is implemented, it would have to go through the RFC process and then the stabilization process before it could be stabilized. Don't expect it anytime soon, especially if you're not using nightly. But it does affect the conversation about whether to propose other language changes to solve your problem.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 24, 2020, 2:09pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/15 "2020-02-24T14:09:08Z")

</div>

@comex I had expected `TryFrom` and `TryInto` to have a similar relationship to `From` and `Into` have. I did **not** expect interdependencies between `TryFrom`/`TryInto` on the one hand and `From`/`Into` on the other. No wonder my attempt failed. Very unintuitive I must say, I still don't understand why a fallible conversion should necessarily trigger an infallible one, and if you happen to know why I'm all ears.

That also means that ditching `TryFrom` and `TryInto` in favor of my own conversion traits is more likely to work.

It effectively also means that the `TryFrom`/`TryInto` traits are defined in a way that, under certain conditions (which are met here), makes them defeat their own purpose.

---

<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:** [February 24, 2020, 5:02pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/16 "2020-02-24T17:02:10Z")

</div>

> [@jjpe](#):
>
> I still don't understand why a fallible conversion should necessarily trigger an infallible one, and if you happen to know why I'm all ears

It's the other way around, `Into` imples `TryFrom`, with the error case being `std::convert::Infallible`. The reason it goes from `Into` to `TryFrom` is detailed in the PR here:

> <https://github.com/rust-lang/rust/pull/56796#issuecomment-447702699>
>
> @sfackler I understand that, but if we want the impl \`TryFrom\` to imply \`TryInto…\`, which I think we do, and we want to keep the impl \`From\` to imply \`Into\`, then the only way to get \`Into\` to imply \`TryInto\` is by going through \`TryFrom\`. Otherwise we could get conflicting impls of \`TryInto\`. This is simply a way to sidestep that. It does look a bit weird, but it is necessary to have the obvious things happen.
> 
> We can think of it like this
> \`From\` implies \`Into\` (and these two traits are semantically equivalent)
> \`Into\` implies \`TryFrom\` (this impl stitches together fallible and infallible conversions)
> \`TryFrom\` implies \`TryInto\` (similar to how \`From\` implies \`Into\`, \`TryFrom\` and \`TryInto\` are semantically equivalent, so this impl must exist in one form or another)
> 
> Another way to do it would be to do
> \`From\` implies \`Into\`
> \`Into\` implies \`TryInto\`
> \`TryInto\` implies \`TryFrom\`
> 
> This would also work, and may be easier to think about.
> 
> \---
> If we don't want to change the \`TryFrom\` implies \`TryInto\` impl, then the only way to get all infallible conversions to have fallible equivalents (where the \`Err\` is \`!\`), is to have \`Into\` imply \`TryFrom\`.
> Or we could chave \`Into\` imply \`TryInto\` and \`TryInto\` imply \`TryFrom\`, and that would pipeline all conversions.
> 
> \---
> Overall, having a tree structure for this would be bad, as it would punish some impls for reasons beyond their control. So I want to have a linear structure.
> 
> Tree:
> \`From\` -\> \`TryFrom\` -\> \`TryInto\`
> L\> \`Into\`
> 
> Linear:
> \`From\` -\> \`Into\` -\> \`TryFrom\` -\> \`TryInto\`
> or
> \`From\` -\> \`Into\` -\> \`TryInto\` -\> \`TryFrom\`

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 24, 2020, 5:25pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/17 "2020-02-24T17:25:54Z")

</div>

I see.

All the same, assuming that my guess works out\*, I think I made the right choice in duplicating (at least in spirit) `TryFrom` and `TryInto` as it also allows me to change the trait signatures while I'm at it.

\*which it seems to, but I'm not done yet

---

<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:** [February 24, 2020, 6:21pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/18 "2020-02-24T18:21:18Z")

</div>

I'm still not certain why you need a custom `Box` variant in the first place. The rough expansion I'm imagining is

```rust
trait Diff {
    type Diff;
    fn diff(left: &Self, right: &Self) -> Self::Diff;
    fn apply(to: &mut Self, diff: Self::Diff);
}

struct [<#type Diff>] {
  #(
    #field: <#field_type as Diff>::Diff,
  )*
}

impl Diff for #type {
    type Diff = [<#type Diff>];
    fn diff(left: &Self, right: &Self) -> [<#type Diff>] {
        [<#type Diff>] {
          #(
            #field: Diff::diff(&left.#field, &right.#field),
          )*
        }
    }
    fn apply(to: &mut Self, diff: [<#type Diff>]) {
      #(
        Diff::apply(&mut to.#field, diff.#field);
      )*
    }
}

```

I fail to see the real requirement of custom container types here, though it is, of course, possible that I missed something.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [February 24, 2020, 6:39pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/19 "2020-02-24T18:39:20Z")

</div>

I neither need nor want a custom Box variant. That would be an ugly hack, which I would be forced to use if using my own trait definitions turn out not to work.

What I need is to be able to derive _any_ necessary impl blocks for some traits for the types that are annotated with a `#[derive(Delta)]`, as well as for the types that are generated in the process. But `#[fundamental]` mucks that up by preventing impl blocks from being written for certain trait/type combos, one of which is `TryFrom` / `Box<T>`.

---

<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:** [February 24, 2020, 7:25pm UTC](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878/20 "2020-02-24T19:25:31Z")

</div>

Ok, straight to the point:

What is the `BoxBar<T>` type used for. (Why does this need to be a distinct type from `Box`.)

[Next page](https://internals.rust-lang.org/t/language-inconsistency-when-implementing-a-trait/11878.md?page=2)
