# Shipping specialization: a story of soundness

**URL:** <https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507>\
**Category:** language design\
**Created:** [July 8, 2017, 7:05pm UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507 "2017-07-08T19:05:18Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)\
**Post date:** [July 17, 2017, 5:15pm UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/21 "2017-07-17T17:15:20Z")

</div>

> [@Fylwind](#):
>
> Something probably has to give, but I do hope it's not lifetime parametricity.

It can't be. We rely on it for soundness (e.g. in `RefMut::map`).

---

<div class="post-metadata">

**Author:** ![Ericson2314](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ericson2314/32/246_2.png) [@Ericson2314](https://internals.rust-lang.org/u/Ericson2314)\
**Post date:** [July 19, 2017, 9:30pm UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/22 "2017-07-19T21:30:10Z")

</div>

I suppose that types that only differ re lifetimes have a common supertype? Can we use that semilattice to prevent lifetime specialization with things like the `(T, T)` example?

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [July 20, 2017, 8:04am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/23 "2017-07-20T08:04:27Z")

</div>

@Ericson2314 Does that idea still work if taking into account invariant type parameters?

---

<div class="post-metadata">

**Author:** ![Ericson2314](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ericson2314/32/246_2.png) [@Ericson2314](https://internals.rust-lang.org/u/Ericson2314)\
**Post date:** [July 23, 2017, 1:43am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/24 "2017-07-23T01:43:41Z")

</div>

😕 I was sorta thinking there’s very little true invariance in the heart of Rust if the “latent” ontravariance can be used, but custom parameterized nominal types can’t soundly be replaced with their bodies, of course.

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [July 23, 2017, 10:01am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/25 "2017-07-23T10:01:09Z")

</div>

> [@Ericson2314](#):
>
> I was sorta thinking there’s very little true invariance in the heart of Rust if the “latent” ontravariance can be used

But the heart of Rust is `&mut` and it's invariant. (;

---

<div class="post-metadata">

**Author:** ![Ericson2314](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ericson2314/32/246_2.png) [@Ericson2314](https://internals.rust-lang.org/u/Ericson2314)\
**Post date:** [July 23, 2017, 2:16pm UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/26 "2017-07-23T14:16:49Z")

</div>

I forgot about that too :O. (In stateful MIR I do point out that splitting the intial and final type gets rid of the invariance, but that doesn’t help here.)

Maybe we should disallow aliasing of type parameters unless we forbid their substition with anything involving invariant lifetimes?!

---

<div class="post-metadata">

**Author:** ![rkjnsn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rkjnsn/32/5368_2.png) [@rkjnsn](https://internals.rust-lang.org/u/rkjnsn)\
**Post date:** [July 24, 2017, 12:24am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/27 "2017-07-24T00:24:57Z")

</div>

> That gives us leverage to use something like epochs to make trans smarter over time, while still shipping some version of specialization relatively soon.

I may be misunderstanding something, but isn't trans explicitly out of scope of the epochs RFC, which is targeted at front-end changes?

---

<div class="post-metadata">

**Author:** ![philipc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/philipc/32/4738_2.png) [@philipc](https://internals.rust-lang.org/u/philipc)\
**Post date:** [July 26, 2017, 5:10am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/28 "2017-07-26T05:10:53Z")

</div>

For the final bomb example, since trans knows that the code satisfies typeck, can it switch to treating the associated types as ‘in’ type parameters? So can it use the fact that `s: String` to select the correct specialization? This is assuming that the issues related to lifetime specialization have already been solved for cases that don’t involve associated types.

Or in other words, can trans treat the final bomb example the same as the following code:

```rust
trait Bomb<Assoc: Default> {}

impl<T> Bomb<()> for T {}

impl<T> Bomb<String> for (T, T) {}

fn indirect<T: Bomb<A>, A: Default>() -> A {
    A::default()
}

fn build<T, A1, A2>(t: T) -> A2
    where T: Bomb<A1>,
          (T, T): Bomb<A2>,
          A1: Default,
          A2: Default
{
    indirect::<(T, T), A2>()
}

fn main() {
    let s: String = build("Uh oh");
    drop(s)
}

```

I’m still learning the details of rust, so hope my posts here aren’t too much noise.

---

<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:** [January 26, 2018, 4:49am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/29 "2018-01-26T04:49:01Z")

</div>

Necropost:

I recently read in a random Hacker News comment about "type roles" in Haskell:

> **[roles · Wiki · Glasgow Haskell Compiler / GHC · GitLab](https://gitlab.haskell.org/ghc/ghc/-/wikis/roles)**
>
> The Glorious Glasgow Haskell Compiler.

...and it occurred to me that the problem the feature was meant to solve is pretty similar to the soundness hole here.

The compiler expects to be able to use the same trait/typeclass implementations for two types based on the assumption that they have identical representations:

- Haskell: A `newtype` versus the type it wraps
- Rust: Types that differ only in lifetime parameters

This works for normal (parametric) generic code, but is broken by the ability to create a type-to-type 'lookup table':

- Haskell: …using type families (which are just associated types, in Rust terminology, but because Haskell's type system treats newtypes as separate types, there's nothing preventing you from impl'ing something for a newtype and its base type with different associated types)
- Rust: …using associated types + specialization (specialization is required because the language has only a single concrete lifetime, `'static`, so there's no other way to have two separate `impl`s of the same trait for two types differing only in a lifetime parameter)

Haskell's solution is to differentiate between two 'roles' of type parameters: "representational" parameters, which allow coercions but not lookup, and "nominal" parameters, which allow lookup but not coercions. (By "coercions" I mean the features in first set of bullets, and by "lookup" I mean the second set.)

However, @glaebhoerl [once wrote](https://github.com/rust-lang/rfcs/pull/1210#issuecomment-186008829), about the roles feature:

> The opinion of many leading members of the Haskell community is that this solution was ill-conceived and brings more complexity than it's worth.

And I'm not really sure what an equivalent feature would look like in Rust, anyway.

---

<div class="post-metadata">

**Author:** ![vi0](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vi0/32/750_2.png) [@vi0](https://internals.rust-lang.org/u/vi0)\
**Post date:** [January 27, 2018, 1:30am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/30 "2018-01-27T01:30:29Z")

</div>

> “representational” parameters ..., and “representational” parameters,

Probaby one of them should be changed.

---

<div class="post-metadata">

**Author:** ![aturon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/aturon/32/3272_2.png) [@aturon](https://internals.rust-lang.org/u/aturon)\
**Post date:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507/31 "2019-03-25T08:28:44Z")

</div>

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

[Previous page](https://internals.rust-lang.org/t/shipping-specialization-a-story-of-soundness/5507.md?page=1)
