Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-6120] Bug with Class and Subtype existentials, when protocol doesn't have class requirement #48675

Closed
swift-ci opened this issue Oct 11, 2017 · 3 comments

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 11, 2017

Previous ID SR-6120
Radar None
Original Reporter benasher44 (JIRA User)
Type Bug
Status Closed
Resolution Duplicate
Environment

macOS 10.13.0

Xcode 9.0 (App Store version)

Swift 4 (not in Swift 3 compatibility mode)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 2c5e5e8da3ceaf23dbab95779c64af95

duplicates:

  • 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:

protocol P {
    var foo: String { get set }
}

class A {
}

class B: A, P {
    var foo = ""
}

typealias AandP = A & P

let c: 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.

@belkadan
Copy link
Contributor

belkadan commented Oct 11, 2017

This is correct behavior, if confusing; see SR-142 for more details.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 11, 2017

Comment by Ben A (JIRA)

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?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 12, 2017

Comment by Ben A (JIRA)

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

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants