# Question about specialization of complex types

**URL:** <https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585>\
**Category:** Uncategorized\
**Created:** [June 7, 2016, 8:20pm UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585 "2016-06-07T20:20:07Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![skade](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skade/32/3333_2.png) [@skade](https://internals.rust-lang.org/u/skade)\
**Post date:** [June 7, 2016, 8:20pm UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/1 "2016-06-07T20:20:07Z")

</div>

Hi,

I was trying the following today (with nightly, specialisation turned on):

```
impl<Y: From<X>, X> From<Option<X>> for Option<Y> {
    fn from(self: Option<X>) {
        match self {
            Some(x) => Some(x.from()),
            None => None
       }
   }
}

```

This fails, because there is already a blanket implementation of `From<T> for T`. I was assuming specialization would solve such cases, but it seems not.

Intuitively, I would say that `Option<T>` is more specialized then `T`, but this doesn’t seem to be the case. Curiously though, I have found no mention of these cases in the relevant [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md), nor can I come up with a reason why this would be a problem. I could be wrong though, just because I haven’t found a problematic example doesn’t mean there isn’t one :).

Can someone shed some light in here for me?

([playpen](https://is.gd/EfX0TY))

---

<div class="post-metadata">

**Author:** ![llogiq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/llogiq/32/13692_2.png) [@llogiq](https://internals.rust-lang.org/u/llogiq)\
**Post date:** [June 7, 2016, 9:26pm UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/2 "2016-06-07T21:26:36Z")

</div>

Did you implement this within `std::option`? If not, I’d guess you run afoul of the orphan rule.

Also I doubt you can create a useful implementation of `From<Option<T>> for U` unless you either panic on `None` or require `U : Default`.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [June 7, 2016, 9:34pm UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/3 "2016-06-07T21:34:10Z")

</div>

I agree that `Option<T>` is should be more specialized than `T`, and though the RFC is rather vague (referring only to substituting a type variable with a fully concrete type, rather than with a parameterized type), [it is the case today](https://is.gd/ZpuIPt).

The first problem you are running into is that the from method in the `From<T> for T` impl is not specializable (syntactically, it does not have `default` before the `fn`). You cannot specialize that impl.

I also don’t think this impl is actually specialized from the blanket impl - it is only a subset if `Y=X`, otherwise it is not. Therefore this impl would not be valid even if the blanket impl were specializable.

Lastly you cannot define this impl anywhere except `libcore` because of the orphan rules.

---

<div class="post-metadata">

**Author:** ![skade](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skade/32/3333_2.png) [@skade](https://internals.rust-lang.org/u/skade)\
**Post date:** [June 7, 2016, 11:58pm UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/4 "2016-06-07T23:58:15Z")

</div>

If you both have a look at the linked [playpen](https://is.gd/EfX0TY), I just quickly created my own Option type to get around that for illustration purposes :). (Same for `From`)

Current implementation of std::Option, From and the Orphan rule aside, the problem is conflicting implementations.

> [@llogiq](#):
>
> Also I doubt you can create a useful implementation of `From<Option<T>>`for U unless you either panic on None or require U : Default.

The question here is not to implement for U but for `Option<U>`, which cannot panic if T -\> U doesn't panic. (Basically: If `From` is defined for the type, there's also a `From` for the wrapped type)

> [@withoutboats](#):
>
> I also don't think this impl is actually specialized from the blanket impl - it is only a subset if Y=X, otherwise it is not. Therefore this impl would not be valid even if the blanket impl were specializable.

Ah, I think I understand. So the problem is that the implementation for `Option<X> for Option<Y>` with X!=Y doesn't cover `From<T> for T` while it would it X=Y.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [June 8, 2016, 1:25am UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/5 "2016-06-08T01:25:30Z")

</div>

> [@skade](#):
>
> Ah, I think I understand. So the problem is that the implementation for Option\<X\> for Option\<Y\> with X!=Y doesn't cover From\<T\> for T while it would it X=Y.

Yeah. To write this we would need the lattice form of specialization and then an additional `impl<T> Option<T> for Option<T>` (to cover the 'intersection' between these two overlapping impls).

---

<div class="post-metadata">

**Author:** ![skade](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skade/32/3333_2.png) [@skade](https://internals.rust-lang.org/u/skade)\
**Post date:** [June 8, 2016, 9:04am UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/6 "2016-06-08T09:04:08Z")

</div>

> [@withoutboats](#):
>
> Yeah. To write this we would need the lattice form of specialization and then an additional impl\<T\> Option\<T\> for Option\<T\> (to cover the 'intersection' between these two overlapping impls).

Right.

If I see that right from the RFC, the lattice form of specialization is "just" an extension of the current form and might happen in the future. This seems like a rather usual case for me.

If I read the [tracking issue](https://github.com/rust-lang/rust/issues/31844) right, this is still an open question. I'll move my comments over there.

Thanks for the clarifications! 🙂

---

<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:** [March 25, 2019, 8:26am UTC](https://internals.rust-lang.org/t/question-about-specialization-of-complex-types/3585/7 "2019-03-25T08:26:18Z")

</div>

Closed on March 25, 2019, 8:26am UTC

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