Description
Summarizing what we discussed last month:
A common pattern in InfoTransformer
like ExtensionMethods
is to create new symbols like foo$extension
in the current phase and to add them to the declarations of a class in the next phase. This causes problem when we try to bring forward the denotation corresponding to such a symbol to a subsequent run, because stillValid
considers a denotation to be valid if it's valid in its owner at the first phase it's defined, but at its first phase the symbol has no owner yet!
Here is a testcase:
scala> class Foo(x: Int) extends AnyVal { def foo: Int = 1 }
defined class Foo
scala> new Foo(1).foo
Exception in thread "main" dotty.tools.dotc.core.Denotations$StaleSymbol: stale symbol; method foo$extension#33232 in module class Foo$, defined in Period(12..33, run = 4), is referred to in run Period(13..13, run = 6)
at dotty.tools.dotc.core.Denotations$SingleDenotation.staleSymbolError(Denotations.scala:932)
...
We can extend stillValid
to also check the phase right after the first phase but that's still not enough because InfoTransformers are lazy and the InfoTransformer for the next phase might never have run in the initial run where the symbol was created! I've only been able to reproduce this using the sbt-based bootstrap of dotty by running dotty-compiler-bootstrapped/test-only -- --tests=repl_all
. I currently work around this by explicitly forcing the denotation of extension methods at the phase where they're entered in their owner, but this is just a hack.
@DarkDimius suggested that we always recompute denotations from pickling, doing this may require a lot of work.