# Allow type placeholder for item signatures if they constrain the associated types

**URL:** <https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095>\
**Category:** language design\
**Created:** [March 21, 2018, 12:06am UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095 "2018-03-21T00:06:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![uzytkownik](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/uzytkownik/32/5013_2.png) [@uzytkownik](https://internals.rust-lang.org/u/uzytkownik)\
**Post date:** [March 21, 2018, 12:06am UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/1 "2018-03-21T00:06:52Z")

</div>

I tried to write following code which seems to be disallowed by Rust:

```
trait Foo {
    type Foo;
    fn get_foo(&self) -> &Self::Foo;
}

/* Not allowed
trait Bar1: Foo<Foo = Option<_>> {
    fn bar(&self) -> bool {
        self.get_foo().is_some()
    }
}
*/

/* Verbose as pollutes all usage of this trait */
trait Bar2<S>: Foo<Foo = Option<S>> {
    fn bar(&self) -> bool {
        self.get_foo().is_some()
    }
}

/* Less verbose for my case but awkward and more of a workaround */
trait Bar3: Foo {
    fn bar<S>(&self) -> bool where Self: Foo<Foo = Option<S>> {
        self.get_foo().is_some()
    }
}
```

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 21, 2018, 10:38am UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/2 "2018-03-21T10:38:46Z")

</div>

Right, you’ve invented a nicer syntax that Rust doesn’t support.

```rust
trait Bar2<S>: Foo<Foo = Option<S>> 

```

This means “for each `S`, make a new version of this trait”, which in this case is necessary, because every `Option<S>` may have different layout, and a different way of encoding `Some`, so every call to `is_some()` may be different. Rust just likes to be explicit about it.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [March 21, 2018, 10:58am UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/3 "2018-03-21T10:58:45Z")

</div>

> [@kornel](#):
>
> Right, you’ve invented a nicer syntax that Rust doesn’t support.

Yet 😉 [Tracking issue for trait aliases · Issue #41517 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/41517)

---

<div class="post-metadata">

**Author:** ![uzytkownik](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/uzytkownik/32/5013_2.png) [@uzytkownik](https://internals.rust-lang.org/u/uzytkownik)\
**Post date:** [March 21, 2018, 4:29pm UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/4 "2018-03-21T16:29:05Z")

</div>

> This means “for each S, make a new version of this trait”, which in this case is necessary, because every `Option<S>` may have different layout, and a different way of encoding Some, so every call to i`s_some()` may be different. Rust just likes to be explicit about it.

I'm not sure I'm following. Since type can implement `Foo` only once `Self::Foo` needs to be known during implementation anyway. All `Foo = Option<_>` does is restrict what `Bar2` can be implemented for. The only thing that would be different as far as I can see is that default implementation needs to be generated - but from language user perspective that's an implementation detail.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [March 21, 2018, 6:27pm UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/5 "2018-03-21T18:27:38Z")

</div>

BTW, I mixed up users/internals forums and I thought your post was a question, not a proposal.

I was referring to monomorphisation. There has to be a different `is_some()` call for `Option<&Foo>` (null check) and `Option<Foo>` (extra boolean field). In some way it is an implementation detail, but also it’s visible in the syntax when that approach is used.

---

<div class="post-metadata">

**Author:** ![uzytkownik](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/uzytkownik/32/5013_2.png) [@uzytkownik](https://internals.rust-lang.org/u/uzytkownik)\
**Post date:** [March 22, 2018, 5:18pm UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/6 "2018-03-22T17:18:53Z")

</div>

Doesn’t it need to happen anyway if the trait consumes objects (`fn foo(self, foo: Self)`) as `Self` might take different amount of space? `Self::Foo` is dependent type so if you monomorphise in type of object implementing trait the dependent trait monomorphosation shouldn’t be much different I think.

---

<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:29am UTC](https://internals.rust-lang.org/t/allow-type-placeholder-for-item-signatures-if-they-constrain-the-associated-types/7095/7 "2019-03-25T08:29:56Z")

</div>

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