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-11325] Typechecker can be tricked into giving misleading error #53726

Open
gwynne opened this issue Aug 18, 2019 · 3 comments
Open

[SR-11325] Typechecker can be tricked into giving misleading error #53726

gwynne opened this issue Aug 18, 2019 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@gwynne
Copy link
Contributor

gwynne commented Aug 18, 2019

Previous ID SR-11325
Radar None
Original Reporter @gwynne
Type Bug
Environment

Apple Swift version 5.1 (swiftlang-1100.0.266.1 clang-1100.0.32.1)
Target: x86_64-apple-darwin19.0.0

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

md5: 99b2d073cb3320f826cd08105b8cd79c

Issue Description:

I can't quite figure out what it is about this code that produces this result, but given this input:

import Foundation // for components(separatedBy:)
enum Example: String { case whatever }
let impliedArray = "x".components(separatedBy: " ")
let dict: [String: Codable] = [
    "key1": impliedArray[0],
    "key2": Example.whatever,
].merging(impliedArray.map { ($0, $0) }, uniquingKeysWith: { $1 })

The compiler gives this misleading error:

error: repl.swift:6:21: error: cannot convert value of type 'Example' to expected dictionary value type 'String'
    "key2": Example.whatever,
                    ^

If impliedArray is removed from either of the usage sites (such as replacing it with a literal like ["x"]), the error is much more what one would expect:

error: repl.swift:6:21: error: cannot convert value of type 'Example' to expected dictionary value type 'Codable' (aka 'Decodable & Encodable')
    "key2": Example.whatever,
                    ^

In both cases, adding Codable conformance to the enum immediately silences the error and compilation will succeed.

This appears to require, at the least:

  • At least one of the dictionary's values to come from a variable of inferred array or dictionary type.

  • The input sequence for .merging(_:uniquingKeysWith: ) also come from a variable of inferred array or dictionary type.

The Example type given here can be just about anything not already Codable; for instance, the same issue appears if the declaration is:

struct Example { let x = 0 }
@gwynne
Copy link
Contributor Author

gwynne commented Aug 18, 2019

Possibly related to SR-11220?

@gwynne
Copy link
Contributor Author

gwynne commented Aug 18, 2019

cc @xedin

@xedin
Copy link
Member

xedin commented Aug 19, 2019

@gwynne This is actually expected type-checker behavior. It's going to find a concrete type to unify all elements under, that's why it attempts `String` (inferred from impliedArray) and it would also attempt `Codable` which is protocol, and since we always prefer concrete types over the protocols as a best solution, you'll get an error which talks about `String`. With ["x"] as an element it's a bit different because "x" doesn't have a set type, we only know that literal is supposed to conform to `ExpressibleByStringLiteral` that's why the only possible solution would be to use `Encodable` as a value type.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants