I have a protocol Copyable, that I would like to declare like this:
public protocol Copyable
{
init(other: Self)
}
extension Copyable
{
public func copy() -> Self
{
return type(of: self).init(other: self)
}
}
However, in implementing it, I get the ubiquitous (possibly iniquitous as well) error in code like this:
public required convenience init(other: Property)
{
self.init()
if let copyableValue = other.value as? Copyable // error: Protocol 'Copyable' can only be used as a generic constraint because it has Self or associated type requirements
{
value = copyableValue.copy() as! valueT
}
else
{
value = other.value
}
}
So, I change the protocol to:
public protocol Copyable
{
init(other: Copyable)
}
extension Copyable
{
public func copy() -> Self
{
return type(of: self).init(other: self)
}
}
… and that gets rid of the unusable Self problem in the implementation, but it does mean I have to manually cast the other
parameter to the type of the implementing class in each and every implementation of the copy constructor, like this:
public required convenience init(other: Copyable)
{
self.init()
if let other = other as? Property
{
if let copyableValue = other.value as? Copyable
{
value = copyableValue.copy() as! valueT
}
else
{
value = other.value
}
}
}
What is even more strange is that the copy()
function declaration uses Self and the compiler doesn't complain, it is only if I use Self in the init(:_)
declaration that I get the error.
This seems to be inconsistent as one part of a protocol can use Self without the problem but another causes it.
Any words of wisdom here? Or is this a bug?