Array of Dictionaries, even flatmapped to Tuples, error when using Dictionary(keysAndValues:uniquingKeysWith:)

I’m attempting to use the new Swift 4 methods below to combine an array of dictionaries.

You use this initializer to create a dictionary when you have a sequence of key-value tuples

SE-0165: Dictionary & Set Enhancements

This works great with a sequence of key-value tuples:

let arrayOfTuple = [("one", 1),
                    ("two", 2),
                    ("three", 3)]
// [("one", 1), ("two", 2), ("three", 3)]

// ok!
let tupleDict = Dictionary(arrayOfTuple) { (_, new) in new}
// ["one": 1, "three": 3, "two": 2]

However, it gives an error for the related concept of a sequence of dictionaries:

let arrayOfDict = [
    ["one" : 1],
    ["two" : 2],
    ["three": 3],
// [["one": 1], ["two": 2], ["three": 3]]

// ERROR: generic parameter 'Key' could not be inferred
let dict = Dictionary(arrayOfDict) { (_, new) in new}
// Understandable error, as `arrayOfDict` is not "a sequence of key-value tuples"
// Would be nice if this worked, though...

It also fails with an error if you first flatmap the sequence of dictionaries into a sequence of key-value tuples:

let flatMapped = arrayOfDict.flatMap({ $0 })
// [(key: "one", value: 1), (key: "two", value: 2), (key: "three", value: 3)]

// ERROR: generic parameter 'Key' could not be inferred
let dict = Dictionary(flatMapped) { (_, new) in new}
// `flatMapped` is definitely "a sequence of key-value tuples" - why does this not compile?

This DOES work if you explicitly set the Type of the flatMap result to remove the tuple labels:

let flatMapped: [(String, Int)] = arrayOfDict.flatMap({ $0 })

Why does a tuple like [("one", 1)] work, while [(key: "one", value: 1)] does not?

What version of Swift are you using?

For me, the only errors I get are at the first let dict = .... If I delete that statement, the example compiles without any errors.

This is using a Playground in Xcode Version 9.2 (9C40b), which I believe is Swift 4.0(?)

And yes the let dict = lines were commented out when trying the flatMap version; both error independently of each other.

Yeah I can reproduce this in a 4.0 compiler but not using a ToT compiler. I suspect there’s some oddness about how the tuple argument labels were being handled, @rudkx or @nnnnnnnn might know what changed (for the better, it seems).

Labels are significant in tuple types. IIRC, @nnnnnnnn made a change to the same-type constraint used to remove the labels in the constraint (i.e. T == (Key, Value) rather than T == (key: Key, value: Value)). As a result, if the T doesn’t have labels, it clearly works, and if T does have labels we rely on an implicit conversion from T to the equivalent unlabeled tuple before performing the same-type constraint check.