Skip to content

CS: optional storage key path components are read-only #42363

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

Conversation

AnthonyLatsis
Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis commented Apr 14, 2022

...because optional storage requirements do not support mutations in Swift.

@AnthonyLatsis AnthonyLatsis requested a review from jckarter April 14, 2022 11:02
@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please smoke test

@AnthonyLatsis AnthonyLatsis force-pushed the swift-keypath-objc-optional-component branch from a496021 to 4a0f6ce Compare April 14, 2022 15:39
Copy link
Contributor

@jckarter jckarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@jckarter
Copy link
Contributor

@swift-ci Please test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please clean test macOS

@AnthonyLatsis
Copy link
Collaborator Author

Should I bring this over to 5.7?

@jckarter
Copy link
Contributor

@AnthonyLatsis If you have time, sure!

The failure on the Linux bot looks unrelated, I'll re-run the tests when #42370 is merged.

@jckarter
Copy link
Contributor

@swift-ci Please test

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test macOS

@AnthonyLatsis
Copy link
Collaborator Author

macOS timed out on some url.

@AnthonyLatsis
Copy link
Collaborator Author

@swift-ci please test source compatibility

@AnthonyLatsis AnthonyLatsis merged commit 47d6909 into swiftlang:main Apr 15, 2022
@AnthonyLatsis AnthonyLatsis deleted the swift-keypath-objc-optional-component branch April 15, 2022 11:47
@jckarter
Copy link
Contributor

Hi Anthony! Sorry to bother you again, but we got a report that, with this follow-up fix applied, the compiler crashes on code that looks like this:

import Foundation

@objc public protocol Test {
    @objc optional var prop: Bool { get set }
}

internal class Impl: Test {
    var prop: Bool { true }
}

It isn't obvious to my eyes how, but possibly these changes also made it so that protocol conformance checking thinks that an optional get-set property requirement can be satisfied by a read-only property implementation?

@jckarter
Copy link
Contributor

jckarter commented Apr 18, 2022

Forming a key path to an optional property can still trigger a crash as well:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol ObjCProtocol
@optional
@property (nonatomic, assign) BOOL automation;
@end

NS_ASSUME_NONNULL_END
import ObjCFramework

class Object {
    var item: any ObjCProtocol
    init(item: any ObjCProtocol) { self.item = item }

    var automation: Bool { item[keyPath: \.automation] ?? false }
}

@jckarter
Copy link
Contributor

From more experimentation it looks like there may be a remaining issue with properties whose types are bridged, like BOOL -> Bool or NSString * -> String.

@AnthonyLatsis
Copy link
Collaborator Author

Oof, lucky someone caught this so fast. Thanks for sharing, will start debugging all this by tomorrow!

@AnthonyLatsis
Copy link
Collaborator Author

AnthonyLatsis commented Apr 19, 2022

@jckarter Do you have any tips on how to reproduce the ObjCFramework crash? I tried both -import-objc-header and importing a custom module in conjunction with %target-swift-frontend(mock-sdk: %clang-importer-sdk), but IR generation passes. SIL looks sensible too (at the very least the _convertObjCBoolToBool thunk is called).

Edit: Never mind, turns out my previous commit fixed that as well 🤦🏼‍♂️

@jckarter
Copy link
Contributor

Edit: Never mind, turns out my previous commit fixed that as well 🤦🏼‍♂️

Sorry, do you mean the previous PR, or a commit not included in this PR?

@AnthonyLatsis
Copy link
Collaborator Author

Sorry, do you mean the previous PR, or a commit not included in this PR?

A local commit that I thought would only fix the conformance issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants