Commits
Doug Gregor committed 2583e2c3b46
[Type system] Infer 'Any' for array elements and dictionary values and 'AnyHashable' for dictionary keys.
The id-as-Any work regressed cases where Swift code could specify
heterogeneous collection literals, e.g.,
var states: [String: Any] = [
"California": [
"population": 37_000_000,
"cities": ["Los Angeles", "San Diego", "San Jose"],
],
"Oregon": [
"population": 4_000_000,
"cities": ["Portland", "Salem", "Eugene"],
]
]
Prior to this, the code worked (when Foundation was imported) because
we'd end up with literals of type [NSObject : AnyObject].
The new defaulting rule says that the element type of an array literal
and the key/value types of a dictionary literal can be defaulted if no
stronger type can be inferred. The default type is:
Any, for the element type of an array literal or the value type of a
dictionary literal, or
AnyHashable, for the key type of a dictionary literal.
The latter is intended to compose with implicit conversions to
AnyHashable, so the most-general inferred dictionary type is
[AnyHashable : Any] and will work for any plausible dictionary
literal.
To prevent this inference from diluting types too greatly, we don't
allow this inference in "top-level" expressions, e.g.,
let d = ["a" : 1, "b" : "two"]
will produce an error because it's a heterogeneous dictionary literal
at the top level. One should annotate this with, e.g.,
let d = ["a" : 1, "b" : "two"] as [String : Any]
However, we do permit heterogeneous collections in nested positions,
to support cases like the original motivating example.
Fixes rdar://problem/27661580.
(cherry picked from commit 22287ddb580dfe4207c37ef1886c062976870c4a)