Skip to content

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

Merged
merged 1 commit into from
Aug 16, 2022

Conversation

simanerush
Copy link
Member

Resolves #60011

@xedin xedin self-requested a review July 31, 2022 02:12
@AnthonyLatsis
Copy link
Collaborator

@swift-ci please smoke test macOS

@AnthonyLatsis
Copy link
Collaborator

@swift-ci please smoke test macOS

@simanerush simanerush force-pushed the collection-literal-bug-fix branch from 1a9e00f to da4a910 Compare August 2, 2022 05:29
@simanerush simanerush force-pushed the collection-literal-bug-fix branch 4 times, most recently from b0e8cd1 to 83b4a8b Compare August 6, 2022 20:36
@xedin xedin self-requested a review August 6, 2022 21:00
@simanerush simanerush force-pushed the collection-literal-bug-fix branch 2 times, most recently from 59348a1 to 5a87a95 Compare August 7, 2022 21:24
@simanerush simanerush changed the title Sema: Look through implicit conversions when diagnosing collection literals with defaulted types Sema: Emit diagnostics when walking into collection literals with defaulted types Aug 7, 2022
@AnthonyLatsis
Copy link
Collaborator

@swift-ci please smoke test macOS

@simanerush simanerush force-pushed the collection-literal-bug-fix branch from 5a87a95 to bdcf5c9 Compare August 10, 2022 15:47
// Diagnose type defaulted collection literals in subexpressions as
// warnings to preserve source compatibility.
diagnoseTypeDefaultedCollectionExpr(
const_cast<CollectionExpr *>(collection), Ctx,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a const_cast<> here the original E is not const right?

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}}
Copy link
Contributor

Choose a reason for hiding this comment

The 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 [] is used in return i.e. https://github.com/apple/swift/pull/60323/files#diff-55b6c1da2887f7323cf5ddb64f0a2add1f0b6a1392a51113d20bbbd04f8ccfc7R12 because there is a contextual type in this case so it's equivalent to as [Any] or as [Any?] which we suggest to silence the warning.

Copy link
Collaborator

Choose a reason for hiding this comment

The 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 [2, [3]], which is defaulted to [Any] and coerced to Any? as an element of the outer [Any?] literal.

Copy link
Member Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

@xedin xedin Aug 10, 2022

Choose a reason for hiding this comment

The 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.

Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we are also correct to warn on return [] for the same reason. func f() -> some Collection { return [] } is analogous to let _: some Collection = []: there is nothing to infer the element type from.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we warn about let _: [Any] = []?

We should not.

Copy link
Contributor

Choose a reason for hiding this comment

The 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 [Any] similar to this one:

func test() -> [Any] {
  []
}

Copy link
Contributor

Choose a reason for hiding this comment

The 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 // FIXME comment for all the test-cases mentioned in https://github.com/apple/swift/pull/60323/files#r942866744. That could be addressed separately.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func test() -> [Any] {
  []
}

@simanerush Could you add test cases for this and let _: [Any] = [] as you fix the conflict?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -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}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another instance of let _: [Any?] = [1, [2, [3]]] - we shouldn't diagnose it because there is an explicit coercion here.

Copy link
Collaborator

Choose a reason for hiding this comment

The 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?

if (c->getNumElements() == 0) {
InFlightDiagnostic inFlight =
diags.diagnose(c->getLoc(), diag::collection_literal_empty);
inFlight.highlight(c->getSourceRange());
Copy link
Contributor

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?

Copy link
Collaborator

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 tailored diag::collection_literal_empty that requires us to specify an unstated explicit type.

Copy link
Contributor

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe could offer a fix-it with an element IDE placeholder e.g. as [<#Element#>]?

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.

@simanerush simanerush force-pushed the collection-literal-bug-fix branch 3 times, most recently from b696c0c to fe28cd6 Compare August 16, 2022 04:35
…aulted types

Resolves swiftlang#60011

Gardening: clean up `checkTypeDefaultedCollectionExpr` function
@simanerush simanerush force-pushed the collection-literal-bug-fix branch from fe28cd6 to f608802 Compare August 16, 2022 04:45
@AnthonyLatsis
Copy link
Collaborator

@swift-ci please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

collection literal could only be inferred to diagnostic not shown in the presence of a contextual type
4 participants