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-12321] False positive warning: cast always fails from 'Encodable' to '[String: Encodable]' #54751

Closed
adam-fowler opened this issue Mar 4, 2020 · 9 comments
Labels
compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@adam-fowler
Copy link

Previous ID SR-12321
Radar rdar://problem/60230608
Original Reporter @adam-fowler
Type Sub-task
Status Closed
Resolution Done
Environment

Catalina 10.15.3

XCode Version 11.4 beta 3 (11N132i)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Sub-task, TypeChecker
Assignee None
Priority Medium

md5: 2d537e3024f17654a411b6562c8ba1cc

Parent-Task:

  • SR-13088 False positive warning "cast always fails"

Issue Description:

Since updating to XCode 11.4 beta 3 the following code

func encodableCast(_ e: Encodable) {
      let f = e as? [String: Encodable]
      print(f?.description ?? "nil")
 }
let d: [String: String] = ["a": "test", "b": "test2"]
encodableCast(d)

generates a warning

Cast from 'Encodable' to unrelated type '[String : Encodable] always fails

at the line

     let f = e as? [String: Encodable]

Even though the warning states it will fail when you run the code the cast doesn't fail. Previously in Swift 5.1 the cast worked as well, but there was no warning.

@theblixguy
Copy link
Collaborator

Hmm, when we cast from an existential type to a non-existential type (i.e. a concrete type), we check if that type we're casting to conforms to the protocol or not. Dictionary conforms to Encodable when Key and Value conform to Encodable. However, here the Value is Encodable and Encodable does not conform to itself and hence [String: Encodable] does not conform to Encodable, so I can see why the typechecker would think that this cast would fail, as it does not know that you're passing in a value of type [String: String] at call site which does conform to Encodable.

In the meantime, what you can do is something like this:

func encodableCast<T: Encodable>(_ e: T) {
  let f = e as? [String: Encodable]
  print(f?.description ?? "nil")
}

which should avoid triggering that warning.

cc @xedin @hborla

@adam-fowler
Copy link
Author

@theblixguy I can see what you are saying about Encodable not conforming to Encodable. If that is the case though how come the cast works when I run the code.

The full version of the code is actually based on a function from the JSONEncoder in swift-corelibs-foundation (https://github.com/apple/swift-corelibs-foundation/blob/d492e580e9c1fc6491087f96dca896e4412eb138/Foundation/JSONEncoder.swift#L889).

@theblixguy
Copy link
Collaborator

I was talking from the typechecker's perspective, not the runtime. What it's trying to do is check if [String: Encodable] conforms to Encodable or not. As explained above, it doesn't and hence the warning.

@adam-fowler
Copy link
Author

@theblixguy Well the bug is really about the typechecker and the runtime disagreeing.

@theblixguy
Copy link
Collaborator

Yeah, I agree. I’m not sure what the best solution is - we can change the wording of the diagnostic to say that the cast “might/may fail” instead of “always fails”, we can add more special cases or we can remove the check completely (which would be a bit of a loss as it’s quite helpful in a lot of cases).

@beccadax
Copy link
Contributor

beccadax commented Mar 9, 2020

@swift-ci create

@xedin
Copy link
Member

xedin commented Mar 16, 2020

@theblixguy I guess in positions like this (key, value type of the dictionary or element type of a collection) it's safe to assume that `Key`, `Value` is a value of protocol type which would be substituted to the correct type in the runtime? I think it make sense for conformance check in such cases to allocate archetype and add a conformance to it just like we do in constraint system for elements of the collection. Overall I think it would be best to move all such checks into constraint system and check while search for solution instead of post-application.

@LucianoPAlmeida
Copy link
Collaborator

This is fixed on master, @adam-fowler can you please verify on the next available snapshot and close? Thanks 🙂

@adam-fowler
Copy link
Author

verified

@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
compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

5 participants