# Automatically inferring associatedtype when conforming to a refinement

**URL:** <https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407>\
**Category:** Using Swift\
**Created:** [April 20, 2019, 1:22am UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407 "2019-04-20T01:22:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![marcrasi](https://avatars.discourse-cdn.com/v4/letter/m/ec9cab/32.png) [@marcrasi](https://forums.swift.org/u/marcrasi)\
**Post date:** [April 20, 2019, 1:22am UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407/1 "2019-04-20T01:22:37Z")

</div>

I'm seeing some weird associatedtype inference behavior when conforming to a refinement of a protocol that has an associatedtype:

```swift
protocol P1 {
  associatedtype Input
  func req(_ input: Input)
}

protocol P2: P1 {
  func req2(_ input: Input)
}

extension P2 {
  func req(_ input: Input) { req2(input) }
}

struct S: P2 {
  func req2(_ input: String) { print(input) }
}

```

Gives error:

```nohighlight
badassoc2.swift:14:8: error: type 'S' does not conform to protocol 'P2'
struct S: P2 {
       ^
badassoc2.swift:15:8: note: candidate has non-matching type '(String) -> ()'
  func req2(_ input: String) { print(input) }
       ^
badassoc2.swift:14:8: error: type 'S' does not conform to protocol 'P1'
struct S: P2 {
       ^
badassoc2.swift:7:8: note: protocol requires function 'req2' with type '(S.Input) -> ()'; do you want to add a stub?
  func req2(_ input: Input)
       ^
badassoc2.swift:2:18: note: protocol requires nested type 'Input'; do you want to add it?
  associatedtype Input
                 ^

```

It seems like the compiler should be able to figure out the type of `Input` without any extra help from me. Is this a compiler bug? Or something that I should not expect the compiler to be able to do for me?

I have discovered that I can fix it by adding the line `associatedtype Input` to `protocol P2`.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [April 20, 2019, 1:59am UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407/2 "2019-04-20T01:59:31Z")

</div>

I believe this is a known shortcoming, and it affects the standard library as well. The solution employed there is the same one you found, namely adding the `associatedtype` to the refining protocol.

For example, here’s the first few lines of [`BidirectionalCollection`](https://github.com/apple/swift/blob/5c941e0e2168132c3a8f2455ef4ed857adc6c71e/stdlib/public/core/BidirectionalCollection.swift#L38):

```swift
public protocol BidirectionalCollection: Collection
where SubSequence: BidirectionalCollection, Indices: BidirectionalCollection {
  // FIXME: Only needed for associated type inference.
  override associatedtype Element
  override associatedtype Index
  override associatedtype SubSequence
  override associatedtype Indices
  ⋮
}

```

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [April 20, 2019, 11:38am UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407/3 "2019-04-20T11:38:04Z")

</div>

Putting on my Swift Evolution hat…

Is there any scenario in which we _don’t_ want this behavior? As in, could we just tell the compiler to, essentially, automatically insert `override associatedtype XYZ` for every associated type of the parent protocol? Are there any drawbacks to doing so?

---

<div class="post-metadata">

**Author:** ![anthonylatsis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anthonylatsis/32/39232_2.png) [@anthonylatsis](https://forums.swift.org/u/anthonylatsis)\
**Post date:** [April 20, 2019, 12:52pm UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407/4 "2019-04-20T12:52:47Z")

</div>

Associated type inference is intentionally [limited](https://github.com/AnthonyLatsis/swift-evolution/blob/master/proposals/0108-remove-assoctype-inference.md) to a single level for performance reasons. The associated type inference engine was notorious for how unstable and bogus it could be. Not because of quality of implementation – improving the performance of type inference is itself a very complex problem fundamentally.

> [@\[Pitch\] Remove type inference for associated types](https://forums.swift.org/t/pitch-remove-type-inference-for-associated-types/3135/23):
>
> Dave is dramatically understating the pain that this inference has caused. Because this is the only place we do global type inference, it’s put tremendous pressure on the type checker that caused a huge number of bugs, crashes, and outright incomprehensible behavior. I reimplemented the inference of associated type witnesses in April of 2015 ([Reimplement inference of type witnesses with a separate non-recursive… · apple/swift@126e404 · GitHub](https://github.com/apple/swift/commit/126e404fe5bf0be81206f22c83a61f6689d18854), for reference), when the existing implementation unbearable. It got _far_ better, but it’s still not global _enough_ to actually be predictable, and the legacy of this mis-feature manifests in a number of weird ways (e.g., typealiases in protocol extensions cannot be used to satisfy associated type requirements, weird rules for when a defaulted associated type gets used).

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [April 20, 2019, 1:12pm UTC](https://forums.swift.org/t/automatically-inferring-associatedtype-when-conforming-to-a-refinement/23407/5 "2019-04-20T13:12:20Z")

</div>

> [@anthonylatsis](#):
>
> Associated type inference is intentionally [limited](https://github.com/AnthonyLatsis/swift-evolution/blob/master/proposals/0108-remove-assoctype-inference.md) to a single level for performance reasons.

[Not in citation given]
