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-6628] Tuple conversion not diagnosed correctly #49177

Open
DevAndArtist mannequin opened this issue Dec 16, 2017 · 2 comments
Open

[SR-6628] Tuple conversion not diagnosed correctly #49177

DevAndArtist mannequin opened this issue Dec 16, 2017 · 2 comments
Assignees
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

@DevAndArtist
Copy link
Mannequin

DevAndArtist mannequin commented Dec 16, 2017

Previous ID SR-6628
Radar None
Original Reporter @DevAndArtist
Type Bug
Environment

Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)

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

md5: 20903aa2cecdb9ae00987b53ef6d9364

Issue Description:

Tuples with different labels cannot be implicitly converted. Therefore `array1` should fail because `(key: Int, value: Int) != (x: Int, y: Int)`.

let dictionary = Dictionary<Int, Int>()

// Not diagnosed correctly
let array1: [(x: Int, y: Int)] = dictionary.map { $0 } 
let array2: [(x: Int, y: Int)] = dictionary.map {
  return $0
}

// Cannot convert value of type 'Array<(key: Int, value: Int)>' to specified type '[(x: Int, y: Int)]'
let array3: [(x: Int, y: Int)] = Array(dictionary)
let array4: [(x: Int, y: Int)]  = dictionary.map {
  let tuple = $0
  return tuple /* /* workaround */ as (Int, Int) /* as (x: Int, y: Int) */ */
}
let array5: [(x: Int, y: Int)] = dictionary.map {
  print(type(of: $0)) // when reading from `$0` returned value will also emit an error
  return $0
}
@belkadan
Copy link
Contributor

Yikes, and now it's a source compat issue. @xedin?

@xedin
Copy link
Member

xedin commented Dec 18, 2017

It's possible to convert `[(key: Int, value: Int)]` to `[(x: Int, y: Int)]` through array upcast and tuple-to-tuple coercion. The first two expressions work because result of `map` is converted to contextual where `array3` doesn't work because of a bug in the solver.

The difference between array4/5 here is that Swift type-checks multi-statement closures separately from the main constraint system that's why there is a failure related to `return $0` you observe, since it tries to operate on the tuples directly (instead of arrays of tuples), which as you mentioned leads to failure because there is no direct conversion between tuples with different labels.

The rules here are pretty inconsistent and we definitely need to do something about it...

@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