Details
-
Type:
Bug
-
Status: Resolved
-
Priority:
Medium
-
Resolution: Done
-
Component/s: Compiler
-
Labels:
-
Environment:
Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
-
Radar URL:
Description
Summary
In a function using Generics, the generic type will sometimes resolve Self statically instead of dynamically:
func buggy<T where T: AProtocol>(cls: T.Type) { // when calling with a subclass of the conforming type // T is resolved as the subtype but T.someStaticVar uses the parent implementation }
Minimalistic Reproduction code
protocol TypeDescribable { static var typeDescription: String { get } } extension TypeDescribable { static var typeDescription: String { return String(Self) } } class ParentClass: TypeDescribable {} class ChildClass: ParentClass {} func dump<T where T: TypeDescribable>(cls: T.Type) { print("T=\(T.self) but T.typeDescription=\(T.typeDescription)") } dump(ChildClass) // Prints: "T=ChildClass but T.typeDescription=ParentClass" ChildClass.typeDescription // = ChildClass
More complete example
A more complete sample code reproducing the same issue is available as a gist here.
Actual Result
In the context of the dump<T> function, T is resolved as the type ChildClass but T.typeDescription calls the implementation of ParentClass.typeDescription not the one of ChildClass.typeDescription.
Making the protocol constrained to a class doesn't alter the behavior.
Expected Result
As T is resolved as ChildClass the call to T.typeDescription should call the implementation of ChildClass.typeDescription
Additional References
This issue has been confirmed by Joe Groff in this Twitter conversation
This behavior was first spotted in the context of my Reusable library and is also discussed in this issue on the lib repo.