Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WIP: run refchecks for diagnostics after typer errors #11030

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

Open
wants to merge 2 commits into
base: 2.13.x
Choose a base branch
from

Conversation

cvogt
Copy link
Contributor

@cvogt cvogt commented Mar 28, 2025

Looking for feedback:

We'd love to have IDE diagnostics for things detected in refchecks even when typer reported errors. (also see scala/scala3#22872). For example, we have users used to seeing missing implementations for abstract methods in Scala 2 IntelliJ diagnostics, but missing them via metals.

I ran an expertiment running refchecks after typer reported errors and got the relevant test to pass. I want to share the results of the experiment. Please let me know if this sounds worth it for me to further pursue and polish.

Motivation: Running refchecks unlocks the following diagnostics even when having type errors.

  • error: object creation impossible.
    Missing implementation:
    def …: … = ??? // variables need to be initialized to be defined
  • error: method … overrides nothing
  • error: in … multiple overloaded alternatives of method … define default arguments.
  • error: @throws only allowed for methods and constructors
  • error: Java annotation … may not appear multiple times on method …
  • error: incompatible type in overriding
  • error: illegal inheritance;
    trait … inherits different type instances of trait …:
  • error: covariant type … occurs in contravariant position in type … of method …
  • error: object … in package … is marked @experimental and therefore its enclosing scope must be experimental.
  • error: cannot override final member
  • warning: shadowing a nested class of a parent is deprecated but class … shadows class … defined in class …; rename the class to something else
  • warning: value … in class … does nothing other than call itself recursively
  • warning: method… is deprecated (since …): …
  • warning: a pure expression does nothing in statement position
  • warning: Name … is already introduced in an enclosing scope as value .. in class Test. Did you intend to match it using backquoted ?

For each failed test I made a quick call to either add the diagnostics to the test log, fix the test code to satisfy the new diagnostics or add a condition to refchecks to skip the check. If this were to go forward, polishing would require revisiting the decisions.

Open question:

  • Are some of the new diagnostics prone to false positives in the light of type errors? Nothing immediately stuck out in the partests.

  • What would be the best way to deal with the new edge cases handled in RefChecks that make this possible?

    Some thoughts:

    Most of these typerReportedErrors conditions prevent assertion failures or null pointer exceptions. The current conditionals I put there are actually rejecting more cases than necessary.

    More precise would be checking for the exact conditions, e.g. something being null.

    An alternative more wholesale approach would be simply catch and ignore any exception that actually occurs in this best effort mode of refchecks. This might make the mode more resilient against crashes in potential gaps in partest coverage. But it might be too blunt of an instrument even when only used in this best-effort mode.

@scala-jenkins scala-jenkins added this to the 2.13.17 milestone Mar 28, 2025
@cvogt
Copy link
Contributor Author

cvogt commented Mar 29, 2025

source-dependencies/nested-type-params and a few of the source-dependencies/* tests are failing. how do I run those locally?

@lrytz
Copy link
Member

lrytz commented Mar 31, 2025

how do I run those locally?

https://github.com/scala/scala/blob/v2.13.16/build.sbt#L988-L994 - I should add that to CONTRIBUTING.md.

@lrytz
Copy link
Member

lrytz commented Mar 31, 2025

a few of the source-dependencies/* tests are failing

Actually, they are pending tests, so nothing failed. The reporting is very confusing..

@lrytz
Copy link
Member

lrytz commented Mar 31, 2025

I'm not against this, behind a flag (-Y, maybe later -X). I wouldn't expect it to ever be enabled by default though (#9145 (comment)).

@cvogt
Copy link
Contributor Author

cvogt commented Apr 1, 2025

@lrytz -Y flag sounds good 👍 . Maybe -Ybest-effort-refchecks?

I'll work on the change. I'll also make the proposed changes to RefChecks a bit more specific, e.g. instead of

          else if (global.typerReportedErrors) null // because fn.tpe.params can be empty list

this

          else if (global.typerReportedErrors && fn.tpe.params.isEmpty)

And I will undo my changes to the general neg partests. Instead for regression testing I'll copy selected tests with enabled -Ybest-effort-refchecks that triggered the crashes and a few happy path tests, that show the new diagnostics.

Let me know if you have concerns about this.

@lrytz
Copy link
Member

lrytz commented Apr 2, 2025

Let's also see what they say on the Scala 3 side, I think we should do the same on both sides. I can bring it up for discussion in the meeting today.

@lrytz
Copy link
Member

lrytz commented Apr 2, 2025

I can bring it up for discussion in the meeting today

We didn't have enought time, unfortunately..

@som-snytt
Copy link
Contributor

I haven't looked yet, but IMHO the goal would be to factor out some benign refchecks that can always be run when erroring after typer, much like -Wunused runs at that time. I've forgotten now if warnings are allowed to compete with typer errors or if they are ignored.

I don't know if signal/noise would be poor. If I typo a parent class, all my overrides are broken. So maybe only some checks are run, depending on the errors.

@lrytz
Copy link
Member

lrytz commented Apr 23, 2025

@cvogt we discussed this today at the core meeting. We support having a -Y flag for this mode (on both Scala 2 and 3). I think running only refchecks directly after an erroneous typer run makes more sense as phases might crash due to the violated assumptions. On Scala 3 you'd need to run elimRepeated as well, according to Martin.

I think it's unlikely to make it out of a -Y flag though, the concerns have been stated here / on related tickets

  • phases after typer may crash (including refchecks itself)
  • skipping phases (eg, plugins) may lead to other issues, false errors
  • signal/noise might be poor, as Som points out; a single typer error may lead to many refchecks errors

Maybe there's a way for you to try this out with a local Scala build, to get some data on how useful / bad it is? That would be great.

@cvogt2
Copy link

cvogt2 commented Apr 23, 2025

@lrytz that's great, thank you. A -Y flag is perfectly fine. And yes, I think we can trial that with several users on Scala 2 in daily real world use before merging. I'd make PRs for Scala 2 and 3. Just a heads up, the next few months are a bit unpredictable for me, it might take until July/August until I can pick this back up.

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.

5 participants