-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Parse] Do not parse generic arguments of a cast destination if the token is more than a <
#60088
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
Conversation
@swift-ci please smoke test macOS |
@swift-ci please smoke test Linux |
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.
Looks great overall!
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.
Thanks! One more thing.
@swift-ci please smoke test macOS |
<
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.
Makes sense to me! @rintaro please take a look as well!
@swift-ci please smoke test |
|
Co-authored-by: Luciano Almeida <[email protected]>
@swift-ci please test |
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.
Sorry for the late reviewing 🙇
if (startsWithLess(Tok)) { | ||
auto genericArgsStatus = parseGenericArguments(GenericArgs, LAngle, RAngle); | ||
if (genericArgsStatus.isErrorOrHasCompletion()) | ||
return genericArgsStatus; | ||
// Only attempt to parse a generic argument list in a cast destination | ||
// type if the token text is just "<", because it can be an operator, | ||
// for example: "1 as Int16 << 7". | ||
if (Tok.getText().equals("<") || | ||
reason != ParseTypeReason::CastDestination) { |
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.
Can't we just use canParseAsGenericArgumentList()
instead of startsWithLess(Tok)
like expression parsing?
It only accepts single <
, but I'm not sure there's a place we need to accept <<
for a generic arguments in the first place. If we cannot use canParseAsGenericArgumentList()
, could you add some code-comment to explain why not?
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 don't use canParseAsGenericArgumentList()
probably because of the SIL type parsing which has generic function types like <T> (T) -> Void
. And for non-expression position, we probably want to diagnose errors inside <...>
as a generic argument error, but not as a bogus random tokens after a type. E.g.
let a: Dictionary<String: Int>
The error in <String: Int>
should be diagnosed as like expected ',' instead of ':'
inside parseGenericArguments()
. But if we used canParseAsGenericArgumentList()
here, it would be parsed as a random tokens after let a: Dictionary
.
So I think having ParseTypeReason::CastDestination
actually makes sense. And we can use canParseAsGenericArgumentList()
only for CastDestination
case.
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.
Thank you for the feedback!
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.
This embeds a form of unbounded lookahead in the Swift type grammar. We should be careful committing to additional lookahead like this to disambiguate parses. This is strictly a change to the language and should probably be discussed on evolution.
As discussed in #60146, I don't mind if we use unbounded lookahead to diagnose this case, but to accept this production as a result of a lookahead is a much bigger change than I think you intend to make here. |
I don't think a lookahead changes the behavior for currently accepted cases. Currently at this position, all I agree this might be strictly a change to the language, but I don't think this would break any existing code. |
@CodaFi I agree with you in some sense, I was also afraid that that might be a bigger change than just a small bug fix. As we can see, this fix had already caused concern with |
Co-authored-by: Rintaro Ishizaki <[email protected]>
I tend to agree with Robert we should be more principled and farsighted in approaching disambiguation problems that require unbounded lookahead in the general case. The ambiguity can easily be worked around, and I would not want this to ever hinder a hypothetical proposal on dependent types. For now though, we can learn from Rust and improve the diagnostic. @simanerush WDYT? |
@AnthonyLatsis I agree with you. Should I close this PR then and open an issue proposing new diagnostics rather than silencing the current diagnostics? |
Sounds good. |
Resolves #43053.