You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SR-142 mutating function in protocol extension erroneously requires var declaration of class variables
Issue Description:
In order to mutate class-type existentials, protocols used in the existential must have a class requirement. This seems like a bug. Consider the following Swift code with class A, subclass B, and protocol P:
protocolP {
varfoo: String { getset }
}
classA {
}
classB: A, P {
varfoo = ""
}
typealiasAandP = A & Pletc: AandP = B()
c.foo = ""
In Swift 4, this generates the error:
test.swift:16:7: error: cannot assign to property: 'c' is a 'let' constant
c.foo = ""
~ ^
test.swift:14:1: note: change 'let' to 'var' to make it mutable
let c: AandP = B()
^~~
var
Since AandP must be a class type, this seems odd. Including AnyObject in the existential doesn't help. The only fix appears to be make declaring P as protocol P: class. This is unfortunate, since in the real project I want to use UIView & UITextInput to represent any text input view. I can't configure the view using configuration available via UITextInput due to this constraint, and I can't update the UITextInput protocol to have a class requirement because the protocol lives in UIKit.
The text was updated successfully, but these errors were encountered:
It makes sense when we only know that the instance conforms to the protocol and nothing else, since the underlying type could be a struct. This seems more strange now that Swift has class and subtype existentials. There is enough type information here for this to not be an error (I suppose there was in SR-142 as well), since the type must be a class in this case (and in the case in SR-142). I understand that in the end, I'm calling a mutating method on a let; this just seems to be an unfortunate limitation when the explicit type is a class.
On a different note, the actual protocol I'm dealing with is UITextInput from UIKit. Up the chain, it conforms to NSObjectProtocol. Shouldn't that mean that the UITextInput protocol has a class requirement?
Okay. I was able to derive the actual bug I was experiencing in the real-world use case. It turns out this all works fine in the real-world case, when the property is not @optional. Filed a new bug here: SR-6134
Environment
macOS 10.13.0
Xcode 9.0 (App Store version)
Swift 4 (not in Swift 3 compatibility mode)
Additional Detail from JIRA
md5: 2c5e5e8da3ceaf23dbab95779c64af95
duplicates:
var
declaration of class variablesIssue Description:
In order to mutate class-type existentials, protocols used in the existential must have a class requirement. This seems like a bug. Consider the following Swift code with class A, subclass B, and protocol P:
In Swift 4, this generates the error:
Since
AandP
must be a class type, this seems odd. IncludingAnyObject
in the existential doesn't help. The only fix appears to be make declaring P asprotocol P: class
. This is unfortunate, since in the real project I want to useUIView & UITextInput
to represent any text input view. I can't configure the view using configuration available viaUITextInput
due to this constraint, and I can't update theUITextInput
protocol to have aclass
requirement because the protocol lives in UIKit.The text was updated successfully, but these errors were encountered: