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-11184] Cannot assign to key path with IUO base #53581

Closed
hamishknight opened this issue Jul 22, 2019 · 3 comments
Closed

[SR-11184] Cannot assign to key path with IUO base #53581

hamishknight opened this issue Jul 22, 2019 · 3 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself key paths Feature: key paths (both native and Objective-C) type checker Area → compiler: Semantic analysis

Comments

@hamishknight
Copy link
Collaborator

Previous ID SR-11184
Radar None
Original Reporter @hamishknight
Type Bug
Status Closed
Resolution Done
Environment

Swift version 5.1-dev (LLVM 200186e28b, Swift ea894d08b8)
Target: x86_64-apple-darwin18.5.0

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, KeyPaths, TypeChecker
Assignee @LucianoPAlmeida
Priority Medium

md5: 2cd9f154acb864bfc041d6c1d4aabac5

Issue Description:

The following cases fail to compile:

class C {}

func foo(_ c: C!, _ kp: ReferenceWritableKeyPath<C, String?>, _ str: String) {
  // error: Value of optional type 'String?' must be unwrapped to a value of type 'String'
  c[keyPath: kp] = str 
  c![keyPath: kp] = str
  c?[keyPath: kp] = str 
}

However they really should all compile.

If the parameter c is changed from being C! to C?, then the latter two cases correctly compile.

@belkadan
Copy link
Contributor

cc @xedin

@mattneub
Copy link

mattneub commented Jan 9, 2020

My example (https://stackoverflow.com/questions/59653363/more-about-the-weird-behavior-of-referencewritablekeypath-with-an-optional-prope) is a little different but I think it's the same phenomenon?

`self.iv` is a typical IBOutlet property declared as an IUO:

    let im = UIImage()
    let kp = \UIImageView.image
    self.iv[keyPath:kp] = im // error

But now watch this. Instead of an outlet, I'll just make an image view:

    let im = UIImage()
    let kp = \UIImageView.image
    let iv = UIImageView()
    iv[keyPath:kp] = im

That compiles! Why? What semantic / syntactic difference is there between a UIImageView property and a UIImageView local? Is it that the property is an implicitly unwrapped Optional?
To test that idea, let's "propagate" the unwrapping of self.iv explicitly through a local:

    let im = UIImage()
    let kp = \UIImageView.image
    let iv = self.iv!
    iv[keyPath:kp] = im

That compiles too! But we must use a separate local; merely unwrapping self.iv directly is not sufficient:

    let im = UIImage()
    let kp = \UIImageView.image
    self.iv![keyPath:kp] = im // error

Personally I think they should all compile, on the grounds that (1) an implicitly unwrapped optional should behave like the wrapped type, and (2) one should be able to assign the wrapped type to an optional. An image view's `image` is an Optional UIImage so one should be able to assign a UIImage to it (including a UIImage!).

@LucianoPAlmeida
Copy link
Collaborator

cc @hamishknight

@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
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself key paths Feature: key paths (both native and Objective-C) type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants