[swift-users] The case of broken polymorphism or "Cannot convert value of type to expected argument type"?

Isaac Rivera developer at isaacrivera.com
Thu Feb 16 11:05:38 CST 2017


Hello, list!

I am trying to find my way around Swift’s protocol limitations. It appears that in general, any protocol with declared associatedtype will break polymorphism?

Take the case below which does not compile. All "Thing” instances are "Something<VC: UIViewController>” but they can’t be passed around or coerced as so.

How is it that I can legally write the code:

class Thing: Something<UINavigationController> { }

and instantiate it, but it is not the very thing it implements? 

All Thing instances conform to the public interfaces of Something<UIViewController> so why can’t they be recognized as such and coerced as such?

What is the work-around of this break in Polymorphism?

import UIKit

protocol Anything: class, NSObjectProtocol {
	
	associatedtype ViewControllerType: UIViewController
	
	var viewController: ViewControllerType { get }
	
	init(viewController: ViewControllerType)
	
	func addAnything(anything: Something<UIViewController>) -> Bool
}

class Something<VC: UIViewController>: NSObject, Anything {
	
	typealias ViewControllerType = VC
	
	private(set) var viewController: ViewControllerType
	
	required init(viewController: ViewControllerType) { self.viewController = viewController }
	
	final private var things = [String: Something<UIViewController>]()
	
	final internal func addAnything(anything: Something<UIViewController>) -> Bool {
		// implementation details...
		return true
	}
}

class Thing: Something<UINavigationController> { }

let firstThing = Thing(viewController: UINavigationController())
let secondThing = Thing(viewController: UINavigationController())

firstThing.addAnything(anything: secondThing)

// Playground execution failed: error: MyPlayground.playground:48:34: error: cannot convert value of type 'Thing' to expected argument type 'Something<UIViewController>'

firstThing.addAnything(anything: secondThing as Something<UIViewController>)

// Playground execution failed: error: MyPlayground.playground:48:34: error: cannot convert value of type 'Thing' to type 'Something<UIViewController>' in coercion






More information about the swift-users mailing list