Reference to invalid type alias, is this a bug?

I'm not sure but this might be related to the other issues I posted yesterday. This code crashes the compiler in Swift 4 (at least playground seem always to crash) but produces an error message in Swift 5 compiler.

import UIKit

typealias PartialKeyPathSet<Root> = Set<PartialKeyPath<Root>>

protocol _Drivable: AnyObject {}

extension _Drivable {
  typealias Driver = GenericDriver<Self>
  var driver: GenericDriver<Self> {
    get { return GenericDriver<Self>(driving: self) }
    set { /* no-op to allow mutation */ }
  }
}

extension UIView: _Drivable {}

struct GenericDriver<Drivable> {
  let __drivable: Drivable
  init(driving drivable: Drivable) {
    self.__drivable = drivable
  }
}

protocol Configurator {
  associatedtype Drivable: _Drivable
  typealias Driver = Drivable.Driver
  typealias DriverKeyPathSet = PartialKeyPathSet<Driver>
  func configure(_ driver: inout Driver, using set: DriverKeyPathSet)
}

struct AnyConfigurator<Drivable: _Drivable>: Configurator {
  private let _base: Any
  private let _function: (inout Driver, DriverKeyPathSet) -> Void

  init<Other>(_ other: Other)
    where
    Other: Configurator,
    Other.Drivable == Drivable
  {
    _base = other
    _function = other.configure(_:using:)
  }

  // error: Reference to invalid type alias 'Driver' of type 'AnyConfigurator<Drivable>'
  func configure(_ driver: inout Driver, using set: DriverKeyPathSet) {
    _function(&driver, set)
  }
}

Possibly related regression:

Why is the type alias invalid? I assume AnyConfigurator<Drivable>.Driver == Drivable.Driver == GenericDriver<Drivable>.

1 Like

Filed: [SR-10193] Reference to invalid type alias · Issue #52593 · apple/swift · GitHub

3 Likes

Minified:

protocol _Drivable: AnyObject {
    typealias Driver = Self
}

protocol Configurator {
    associatedtype Drivable: _Drivable
    typealias Driver = Drivable.Driver
    func configure(driver: Driver)
}

struct AnyConfigurator<Drivable: _Drivable>: Configurator {
    private let thing: Driver?
    // error: Reference to invalid type alias 'Driver' of type 'AnyConfigurator<Drivable>'
    func configure(driver: Driver) {}
}

It looks suspicious to me, but I'm usually wrong about that kind of stuff...

AnyConfigurator's Driver must be a specific object type known at instantiation (yes?), and from there everything seems like it should be fixed and determinable. It's also suspicious that the remaining elements are all necessary in order to generate the error message. You can't, e.g., omit the function requirement from the Configurator protocol or replace Driver with Drivable.Driver. With those changes, it compiles fine.

What do you mean? That is the current workaround I have to use as the compiler is unable to verify the type alias (I only guess). What I‘m doing there is simply forwarding the typealias from Drivable to the protocol, then to the type that conforms to the protocol.

This issue could be related to another Swift 5 compiler regression regarding type aliases in protocols.

I mean "you can't omit the function requirement from the Configurator protocol, or replace Driver with Drivable.Driver, or any one of a number of other things if you want to reproduce the bug/issue." As far as I can tell, there is no element of the minified example above that can be simplified or removed without failing to cause a compiler error.

2 Likes