The following code snippet was written in playgrounds and it does compile. The code itself represents the code structure from one of my real code bases which emits a compile time error, which I cannot resolve without a boilerplate workaround.
The idea was to move several generic types into protocol typealiases so that every conforming type would automatically know a shortcut alias for that type (the original type is rather long).
It shouldn't be allowed to refer to a generic type without binding its arguments. The playground behavior is a bug. You could write typealias Shortcut<A,B,C> = Generic<A,B,C> to define a generic typealias.
Wait what? I thought that was always a feature similar to how we can sometimes omit the generic parameter list in some contexts like extension Array : Equatable { static func == (lhs: Array, rhs: Array) -> Bool { ... } }:
typealias List = Array // This is a bug, really?
var list = List<Int>()
list.append(1)
Btw. typealias Shortcut = Generic will automatically apply all constraints from the generic parameter list of Generic to Shortcut while typealias Shortcut<A, B, C> = Generic<A, B, C> won't.
The code of the OT copy pasted into a main.swift will compile successfully (I haven't tried with separate files, but I don't see why that should make a difference).
For example the following also compiles and runs:
protocol P {
typealias List = Array
}
struct S : P {
var a: List<Int>
var b: List<Bool>
}
let s = S(a: [1, 2], b: [false, true])
print(s)
But for example:
protocol P {
associatedtype List = Array // ERROR: Reference to generic type 'Array' requires arguments in <...>
}
As I mentioned above it does compile an run fine in the same file, but if you move the types into separate files the compiler starts complaining and I really don't know why. Joe said the way I'm using it is a bug, but that's kind of odd since it feels more like a feature since it allows coping all generic parameter type constraints to the type alias. So to me it feels like the bug is the other way around, but I would really want some more clarification on that.
Which I interpreted as "It works in Playgrounds", and as Playgrounds is too buggy to be trusted for almost any kind of testing I thought it was interesting to know that it does compile as a command line app. : )
Did you try with whole module optimization to see if it made any difference?
Nah it's totally fine ;) I use playground to quickly reproduce issues or sketch out short code snippets. Anyways the issue remains the same across different project setups. In a single file it works, across multiple files the compiler starts hallucinating.
This did the trick, the error message is gone using WMO, but this means I have to use it in debug configuration which as per some WWDC 2018 session will slow down the compilation time.
I reproduced the issue and its definitely a bug. The root cause is we have two different code paths for resolving the underlying type of a type alias; one supports this behavior where generic arguments are not bound, the other does not. Also as you can see there's some disagreement on the team about what the correct behavior is, which is the kind of thing that no doubt leads to two different code paths that do the same thing :-) In any case, it should be an easy fix.
It's definitely a bug that it behaves inconsistently.
I think it was an accidental feature, and I would love if we can remove it because I find it strange to introduce a new generic name without having the generic parameters explicitly written. However, @Slava_Pestov may very well be right that we're stuck with it.