-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Type system] Infer 'Any' for array elements and dictionary values an… #4027
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
[Type system] Infer 'Any' for array elements and dictionary values an… #4027
Conversation
@swift-ci please test |
97f41f9
to
b3dc74b
Compare
@swift-ci please test |
@rudkx can you review? |
var hetero1: DictionaryLiteral = ["a": 1 as NSNumber, "b": "Foo" as NSString] | ||
expectType(DictionaryLiteral<String, NSObject>.self, &hetero1) | ||
|
||
var hetero2: DictionaryLiteral = ["a": 1 as NSNumber, "b": "Foo" as NSString] | ||
expectType(DictionaryLiteral<String, NSObject>.self, &hetero2) | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave this #if/#endif in?
[nevermind, I see the note below...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm working on a fix independently, which should be an small optimization (prior to this PR) that brings back the functionality above.
@DougGregor LGTM! |
@swift-ci please test Linux |
…d '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.
b3dc74b
to
22287dd
Compare
@swift-ci please smoke test and merge |
Now that I've committed the basic 'meet' operation, this no longer regressions anywhere I've seen. |
Grrrr. That Linux failure is the same LLDB issue that's been failing for 7 hours. |
What's in this pull request?
This pull request implements a defaulting rule for the elements of array and dictionary literals.
The id-as-Any work regressed cases where Swift code could specify heterogeneous collection literals, e.g.,
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, orAnyHashable
, 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.,
will produce an error because it's a heterogeneous dictionary literal at the top level. One should annotate this with, e.g.,
However, we do permit heterogeneous collections in nested positions, to support cases like the original motivating example.
Resolved bug number: (rdar://problem/27661580)
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
A smoke test on macOS does the following:
device standard libraries are not built.
version of these tests are not run.
A smoke test on Linux does the following:
tests are not run.
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.
…d 'AnyHashable' for dictionary keys.
The id-as-Any work regressed cases where Swift code could specify
heterogeneous collection literals, e.g.,
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.