-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Sema: Emit diagnostics when walking into collection literals with defaulted types #60323
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// RUN: %target-typecheck-verify-swift | ||
// RUN: %target-typecheck-verify-swift -disable-availability-checking | ||
|
||
struct IntList : ExpressibleByArrayLiteral { | ||
typealias Element = Int | ||
|
@@ -142,19 +142,56 @@ func defaultToAny(i: Int, s: String) { | |
// expected-error@-1{{empty collection literal requires an explicit type}} | ||
let _: Int = a5 // expected-error{{value of type '[Any]'}} | ||
|
||
let _: [Any] = [] | ||
let _: [Any] = [1, "a", 3.5] | ||
let _: [Any] = [1, "a", [3.5, 3.7, 3.9]] | ||
let _: [Any] = [1, "a", [3.5, "b", 3]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
let _: [Any] = [1, [2, [3]]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
|
||
func f1() -> [Any] { | ||
[] | ||
} | ||
|
||
let _: [Any?] = [1, "a", nil, 3.5] | ||
let _: [Any?] = [1, "a", nil, [3.5, 3.7, 3.9]] | ||
let _: [Any?] = [1, "a", nil, [3.5, "b", nil]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}} | ||
let _: [Any?] = [1, [2, [3]]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @simanerush @AnthonyLatsis I think we don't want to diagnose cases like this one (note that it's different from the following one where inner collection literal is heterogeneous) and the ones where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the compiler is correct in this particular case because there is no explicit element type specified for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree. This change originated from @xedin's point earlier on about nested collection literals with a defaulted type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes, I missed that, sorry, this one is indeed correct but the result ones are mentioned are not I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO we are also correct to warn on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We should not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @simanerush It must have been an older commit or something but I could swear I saw a test-case that got updated with the warning that returned
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it's not in the changes anymore I think we can land this with a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@simanerush Could you add test cases for this and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AnthonyLatsis sure! |
||
let _: [Any?] = [1, nil, [2, nil, [3]]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}} | ||
|
||
let a6 = [B(), C()] | ||
let _: Int = a6 // expected-error{{value of type '[A]'}} | ||
|
||
let a7: some Collection = [1, "Swift"] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} {{41-41= as [Any]}} | ||
let _: (any Sequence)? = [1, "Swift"] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
simanerush marked this conversation as resolved.
Show resolved
Hide resolved
LucianoPAlmeida marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let _: any Sequence = [1, nil, "Swift"] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}} | ||
let _ = [1, true, ([], 1)] | ||
// expected-error@-1 {{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
// expected-warning@-2 {{empty collection literal requires an explicit type}} | ||
let _ = true ? [] : [] | ||
// expected-warning@-1{{empty collection literal requires an explicit type}} | ||
let _ = (true, ([1, "Swift"])) | ||
//expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
let _ = ([1, true]) | ||
//expected-error@-1{{heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional}} | ||
|
||
func f2<T>(_: [T]) {} | ||
|
||
func f3<T>() -> [T]? {} | ||
|
||
f2([]) | ||
// expected-warning@-1{{empty collection literal requires an explicit type}} | ||
f2([1, nil, ""]) | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[Any?]'; add explicit type annotation if this is intentional}} | ||
_ = f3() ?? [] | ||
// expected-warning@-1{{empty collection literal requires an explicit type}} | ||
} | ||
|
||
func noInferAny(iob: inout B, ioc: inout C) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,9 +7,13 @@ var x = 1 | |
_ = [x] as [NSNumber] | ||
|
||
_ = ["x":["y":"z","a":1]] as [String : [String : AnyObject]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentiona}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is another instance of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is interesting. Is the inner literal being marked as defaulted by mistake? |
||
_ = ["x":["z",1]] as [String : [AnyObject]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}} | ||
_ = [["y":"z","a":1]] as [[String : AnyObject]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[String : AnyObject]'; add explicit type annotation if this is intentional}} | ||
_ = [["z",1]] as [[AnyObject]] | ||
// expected-warning@-1{{heterogeneous collection literal could only be inferred to '[AnyObject]'; add explicit type annotation if this is intentional}} | ||
|
||
var y: Any = 1 | ||
|
||
|
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.
I see we produce a fix-it in the non-empty case. Should a fix-it be produced here as well?
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.
I think this was a conscious decision: coercing a type-defaulted collection literal to
[Any]
is far less likely to coincide with the programmer's intention if the literal is empty. Hence the tailoreddiag::collection_literal_empty
that requires us to specify an unstated explicit type.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.
I guess it makes sense, I just asked because to me we were suggesting explicit type but missing something actionable as the other case. Maybe could offer a fix-it with an element IDE placeholder e.g.
as [<#Element#>]
? But I agree is ok not emitting, that is just something to think about.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, something along the lines of
; did you mean this to be an instance of 'Swift.Array'?
plus this fix-it would probably be helpful.