Skip to content
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

[annotator] support scala 3.4 irrefutable patterns in for-comprehension #SCL-22274 fixed #660

Closed
wants to merge 5 commits into from

Conversation

disordered
Copy link
Contributor

@disordered disordered commented Apr 29, 2024

This fixes false missing withFilters error for irrefutable patterns in for comprehensions introduced with Scala 3.4 and Scala 3.0 + -source:future.

Related #SCL-22468

def needsPatternMatchFilter(pattern: ScPattern): Boolean =
!pattern.isIrrefutableFor(if (forDisplay) pattern.expectedType else None)
def needsPatternMatchFilter(pattern: ScPattern): Boolean = {
val hasSc3Case = pattern.isScala3OrSource3Enabled &&
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It currently works without this check, however, with Scala 3, when pattern starts with case, compiler will require the right hand to have withFilter.
I believe this check should stay for this reason.

Copy link
Member

Choose a reason for hiding this comment

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

It seems like the check is required, but currently not covered with tests.
It will be more clear once comment is addressed

@disordered
Copy link
Contributor Author

It doesn't address the case where type narrowing occurs (couldn't figure out how to detect type narrowing):

for y :: ys <- List(List(1), List(2)) do println(y)

IntelliJ will not produce an error for Scala 3.4, but compiler will produce this:

pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int]

If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern,
which will result in a filtering for expression (using `withFilter`).
This patch can be rewritten automatically under -rewrite -source 3.2-migration.
    for y :: ys <- List(List(1), List(2)) do println(y)

and Scala 3.0+ will produce the same but as a warning.

@disordered disordered changed the title [annotator] support scala 3.4 irrefutable patterns in for-comprehension #SCL-22274 [annotator] support scala 3.4 irrefutable patterns in for-comprehension #SCL-22274 & #SCL-22468 Apr 29, 2024
@unkarjedy unkarjedy requested review from unkarjedy and sugakandrey and removed request for sugakandrey April 30, 2024 11:04
@unkarjedy
Copy link
Member

unkarjedy commented Apr 30, 2024

Please see this part of our guidelines

Every commit message should reference the YouTrack issue number in format #SCL-XXXXX
Place primary issue number in the end of the first message line
If you have multiple equally-important related issues place them in the end of the first message line
If you have some non-primary, but related issues you can reference them in the commit message body.
In the last commit of a series which fixes an issue, append #SCL-XXXXX fixed to the end of the first message line issue which is fixed. This will close the YouTrack issues automatically when the change is merged into main branch.

Right now the commit message doesn't mention YT issues.
I see the mention in the PR, we can just copy it in the commit itself

import Message.Error

override protected def supportedIn(version: ScalaVersion): Boolean = version >= LatestScalaVersions.Scala_3_0
Copy link
Member

Choose a reason for hiding this comment

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

Let's use the exact version Scala_3_3

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean only to bump to 3.3 or change it to version == LatestScalaVersions.Scala_3_3?
If the latter, why? These tests should pass for all Scala 3 versions (as of right now at least).

EDIT: I just realised there are some incorrect assumptions in the test cases. I'll restructure the tests and then let's take another round on the changes.

}

class ForComprehensionIrrefutableTest_3_future extends ForComprehensionHighlightingTestBase {
Copy link
Member

Choose a reason for hiding this comment

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

Here as well, let's use the exact version Scala_3_3

Copy link
Member

@unkarjedy unkarjedy Apr 30, 2024

Choose a reason for hiding this comment

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

Also, to ensure all the cases are covered, maybe let's inherit from ForComprehensionRefutableTest_3 and override needed tests

(same for Scala 3.4 tests)

!pattern.isIrrefutableFor(if (forDisplay) pattern.expectedType else None)
def needsPatternMatchFilter(pattern: ScPattern): Boolean = {
val hasSc3Case = pattern.isScala3OrSource3Enabled &&
pattern.prevSiblingNotWhitespace.exists(_.getText == ScalaModifier.CASE)
Copy link
Member

Choose a reason for hiding this comment

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

As IntelliJ suggests, please replace _.getText == ScalaModifier.CASE with _.textMatches(ScalaModifier.CASE)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed, though, I don't get that suggestion. Possibly, because I don't have access to plugin com.jetbrains.intellij.api.watcher.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, right the inspection should work in internal mode.
https://github.com/JetBrains/intellij-scala/blob/7a050b30da86b846ca88fa92f51f875b7b805c1d/README.md#prerequisites

(optional but recommended)
Enable internal mode in IDEA to get access to helpful internal actions and debug information

@disordered
Copy link
Contributor Author

disordered commented Apr 30, 2024

Please see this part of our guidelines

Every commit message should reference the YouTrack issue number in format #SCL-XXXXX
Place primary issue number in the end of the first message line
If you have multiple equally-important related issues place them in the end of the first message line
If you have some non-primary, but related issues you can reference them in the commit message body.
In the last commit of a series which fixes an issue, append #SCL-XXXXX fixed to the end of the first message line issue which is fixed. This will close the YouTrack issues automatically when the change is merged into main branch.

Right now the commit message doesn't mention YT issues. I see the mention in the PR, we can just copy it in the commit itself

Want me to force update first commit or just touch up the PR title and description?
Also, should I mention the 22468, if it will auto close it? I think that narrowing should be addressed as well, to make intellij highlight the error, but maybe in a separate PR.

def needsPatternMatchFilter(pattern: ScPattern): Boolean =
!pattern.isIrrefutableFor(if (forDisplay) pattern.expectedType else None)
def needsPatternMatchFilter(pattern: ScPattern): Boolean = {
val hasSc3Case = pattern.isScala3OrSource3Enabled &&
Copy link
Member

@unkarjedy unkarjedy Apr 30, 2024

Choose a reason for hiding this comment

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

Is OrSource3Enabled part needed in this check?
AFAIU the logic should be only about Scala 3 and not about Scala 2.
pattern.isInScala3File should do.

Or even extract val features = pattern.features and use features.isScala3, features.hasSourceFutureFlag

@unkarjedy
Copy link
Member

Want me to force update first commit or just touch up the PR title and description?

Force push to your branch should be ok

@unkarjedy
Copy link
Member

unkarjedy commented Apr 30, 2024

Also, should I mention the 22468, if it will auto close it?

You can omit the "fixed" part and just mention the ticket.
This is still used by our automation

I think that narrowing should be addressed as well, to make intellij highlight the error, but maybe in a separate PR.

Sounds like a good plan.
This issue is less critical compared to irrefutability

…on #SCL-22274 fixed

This fixes false missing withFilters error for irrefutable patterns in for comprehensions introduced with Scala 3.4 and Scala 3.0 + -source:future.

Related #SCL-22468
@disordered disordered changed the title [annotator] support scala 3.4 irrefutable patterns in for-comprehension #SCL-22274 & #SCL-22468 [annotator] support scala 3.4 irrefutable patterns in for-comprehension #SCL-22274 fixed Apr 30, 2024
@disordered
Copy link
Contributor Author

Alright, all comments should be addressed now (including first commit messaging).
I restructured test inheritance a bit. Also, changed the check logic for withFilter requirement as I realized that bulk of tests are run under Scala 2.10 and was not behaving correctly under 3.3 and 3.4.

Should I do something about it?
One option could be to add @RunWithScalaVersions(Array(...)) on ForComprehensionHighlightingTest. If so, I guess with versions 2.13, 3.3 and 3.4?

@unkarjedy
Copy link
Member

Thanks for the contribution!
I will manually cherry-pick the changes and run through our internal CI.
We might even include it in 2024.1 EAP/Release

Should I do something about it?
One option could be to add @RunWithScalaVersions(Array(...)) on ForComprehensionHighlightingTest. If so, I guess with versions 2.13, 3.3 and 3.4?

No, thanks. I will deal with it.

@unkarjedy unkarjedy closed this May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants