Skip to content

Parse failure with < after a cast destination type. #60146

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

Closed
simanerush opened this issue Jul 20, 2022 · 4 comments
Closed

Parse failure with < after a cast destination type. #60146

simanerush opened this issue Jul 20, 2022 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. parser Area → compiler: The legacy C++ parser

Comments

@simanerush
Copy link
Member

simanerush commented Jul 20, 2022

Description
When dealing with cast destination type and a < operator after it, the compiler assumes that the generic arguments list is going to follow the < and produces an expected type error.

Steps To Reproduce
Steps to reproduce the behavior:

  1. Launch Swift.
  2. Run let _ = 1 as Int16 < 7.
  3. Observe the expected type error.

Expected behavior
There should be no expected type error, since < in this context is not supposed to be followed by a generic arguments list.

Environment

  • OS: macOS 12.4
  • Xcode Version: 13.4

Additional context
I fixed issue #43053 which addresses similar problem, but with the<< operator.

@simanerush simanerush added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Jul 20, 2022
@AnthonyLatsis AnthonyLatsis added the parser Area → compiler: The legacy C++ parser label Jul 20, 2022
@CodaFi
Copy link
Contributor

CodaFi commented Jul 25, 2022

This is a fun cross-language disambiguation problem. Consider the (related) classical ambiguous parsing example:

f(a<b,c>(d))

Is a<b,c> meant to be a specialized generic type that is having its initializer invoked with argument d, or are a, b, c, and d actually a fragment of two boolean arguments to f that are being compared via the < and > operators? Bear in mind that both answers are valid parser productions if we parse without retaining a bunch of contextual state (e.g. a symbol table) or performing some amount of unbounded lookahead.

For some context, Rust has the exact same problem.

@tbkka
Copy link
Contributor

tbkka commented Jul 25, 2022

That same Rust thread describes the C# heuristic, which makes a lot of sense to me.

@CodaFi
Copy link
Contributor

CodaFi commented Jul 25, 2022

The current Rust-y answer of using lookahead to emit an extremely helpful diagnostic also works here. The C# solution doesn't feel right to me not just because it fails the "some amount of unbounded lookup" test, but because it precludes the language adopting non-type type parameter arguments without some extra disambiguating tokens.

error: `<` is interpreted as a start of generic arguments for `i16`, not a shift
 --> <source>:3:16
  |
3 |     num as i16 << 7
  |                ^^ - interpreted as generic arguments
  |                |
  |                not interpreted as shift
  |
help: try shifting the cast value
  |
3 |     (num as i16) << 7
  |     +          +

@simanerush
Copy link
Member Author

@CodaFi Thank you for this detailed response. I understand the first problem with some ambiguity concerning <, but your second message is more concerned with <<. One of my currently opened PRs silences the expected type diagnostics in that case. Now, I'm wondering if we even need to silence that if for example Rust doesn't do it but emits helpful diagnostics. Can you please take a look at this PR which addresses << issue? #60088

@simanerush simanerush closed this as not planned Won't fix, can't repro, duplicate, stale Jul 28, 2022
@simanerush simanerush reopened this Jul 28, 2022
@simanerush simanerush closed this as not planned Won't fix, can't repro, duplicate, stale Jul 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. parser Area → compiler: The legacy C++ parser
Projects
None yet
Development

No branches or pull requests

4 participants