Dotty: Overriding an `@varargs` method fails under separate compilation

Created on 29 Jul 2020  路  4Comments  路  Source: lampepfl/dotty

Minimized code

A.scala

import scala.annotation.varargs

trait FirstMixin {
  @varargs
  def counter(name: String*): Int = ???
}

B.scala:

trait Minimization extends FirstMixin {
    override def counter(name: String*): Int = 0
}

Output

Separate compilation of B.scala fails:

$ dotc A.scala
$ dotc -classpath . B.scala
-- [E037] Declaration Error: try/i9463b.scala:3:6 ------------------------------
3 |trait Minimization extends FirstMixin {
  |      ^
  |      method counter overrides nothing

Expectation

Compiles successfully.

bug

Most helpful comment

Thanks for the report, I've updated the issue with a simplified example.

All 4 comments

Thanks for the report, I've updated the issue with a simplified example.

The problem is that in ElimRepeated, we add the varargs forwarder in the tree transformer (transformDefDef) but not in the denotation transformer (transform). When compiling override def counter(name: String*): Int = 0 we correctly realize that a varargs forwarder is needed because it overrides a counter method marked @varargs, so we emit:

override def counter(name: Array[_ <: String]): Int = counter(name: _*)

But the compiler later fails thinking that this isn't actually overriding anything because under separate compilation we only run the denotation transformer for definitions coming from the classpath, so we don't see the forwarder generated for the original @varargs method.

I can think of two ways of fixing this: in addVarArgsForwarder we could simply drop the Override flag if we don't see an overridden definition, this is simple but a bit ad-hoc. Alternatively we could move the creation of the varargs forwarder symbols to the denotation transforme, this would be similar to the static methods we generate for value classes whose symbols are created in the denotation transformer (via createExtensionMethod) and later looked up when creating trees for them in the tree transformer (via extensionMethod), but this would be much more complicated and so probably not worth it. @TheElectronWill do you think you could have a look at this issue?

Yes! I'll have a look.

Okay, so I've tried both. Creating the symbol in transform seems better and isn't _that_ complicated. I'll clean up the code and make a PR.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

noti0na1 picture noti0na1  路  3Comments

mcku picture mcku  路  3Comments

odersky picture odersky  路  3Comments

julienrf picture julienrf  路  3Comments

m-sp picture m-sp  路  3Comments