Skip to content

Incremental compiler does not account for top level definition conflicts #22804

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
jchyb opened this issue Mar 14, 2025 · 1 comment
Open

Comments

@jchyb
Copy link
Contributor

jchyb commented Mar 14, 2025

Compiler version

any

Minimized code

Split across 2 files:
A.scala:

package test

object A
// def a() = ??? // [1]

B.scala

package test

object B
def a() = ???

scalac will not show the issue - use scalacli with a build server (or another built tool):

  1. scala-cli A.scala B.scala
  2. uncomment [1]
  3. scala-cli A.scala B.scala

Output

no error, successful compilation

Expectation

Same error as when initially compiling A.scala and B.scala with uncommented [1], where we get:

[error] ./B.scala:4:1
[error] a is already defined as method a in /Users/jchyb/workspace/scala3/A.scala
[error] 
[error] Note that overloaded methods must all be defined in the same group of toplevel definitions
[error] def a() = ???
[error] ^^^^^^^^^^^^^
@jchyb jchyb added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Mar 14, 2025
@jchyb
Copy link
Contributor Author

jchyb commented Mar 14, 2025

After some research I do not really think it is an issue with a compiler, but it seems moreso with zinc. Conflicts in objects/classes are handled correctly there, but in a somewhat surprising way, where after incrementally compiling the second scala file with a conflicting object/class, zinc chooses to recompile both conflicting classes again, and the compiler then is able to throw the error. What I think happens is that zinc stores links between classes and source files, and if any class is changed it recompiles the linked source files, if there are multiple.

In scala 3, in the ExtractDependencies phase we emit the top level methods as a part of generated package object classes, because of which the above behavior does not occur for those. Ideally, I imagine zinc would be able to unpack those top level methods by itself and create the links to the source files (and I imagine changing anything in the compiler here might end up being a dangerous API change).

I do not have much experience with zinc and incremental compilation, so I can't really speak on what is expected and what not, so I thought it would be safer to issue this here for now.

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

No branches or pull requests

2 participants