Skip to content

Refinements inlined incorrectly #6213

Closed
@milessabin

Description

@milessabin

The following crashes the compiler,

object Test {
  inline def foo[U] <: Any = (??? : { type T = U })

  foo[Int]
}

with,

Exception in thread "main" java.lang.ClassCastException: dotty.tools.dotc.core.Symbols$NoSymbol$ cannot be cast to dotty.tools.dotc.core.Symbols$ClassSymbol
        at dotty.tools.dotc.core.Symbols$Symbol.asClass(Symbols.scala:529)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2015)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2078)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:117)
        at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:2113)
        at dotty.tools.dotc.reporting.TraceSyntax.apply(trace.scala:56)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2106)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
        at dotty.tools.dotc.typer.Typer.$anonfun$typedRefinedTypeTree$1(Typer.scala:1280)
        at dotty.tools.dotc.util.Stats$.track(Stats.scala:37)
        at dotty.tools.dotc.typer.Typer.typedRefinedTypeTree(Typer.scala:1276)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2048)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:117)
        at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:2113)
        at dotty.tools.dotc.reporting.TraceSyntax.apply(trace.scala:56)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2106)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
        at dotty.tools.dotc.typer.Typer.typedType(Typer.scala:2199)
        at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:56)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2029)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2079)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:117)
        at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:2113)
        at dotty.tools.dotc.reporting.TraceSyntax.apply(trace.scala:56)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2106)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2125)
        at dotty.tools.dotc.typer.Inliner.$anonfun$inlined$9(Inliner.scala:510)
        ...

This is a problem both with explicit refinements on the RHS of inline methods, and also with the ones that are desugared to from precise result type annotations on inline methods, ie.,

object Test {
  inline def foo[U]: { type T = U } = ???

  foo[Int]
}

which desugars to the example above.

As far as I can make out the explanation for this is buried in the mechanism(s) used to type and retype RefinedTypeTrees. On initial typing the refinement is given a symbol derived from a synthetic ClassDef which is typed in its place and then recorded as a tree attachement (SymOfTree). This process is repeated during retyping, however ReTyper overrides the method used to retrieve the symbol and doesn't query the attachment, returning tree.symbol instead. This is NoSymbol, hence the resulting stacktrace.

Tweaking ReTyper to pass RefinedTypeTrees though unchanged dodges that problem, but then the symbols for the definitions contained in the refinement are reused which blows up pickling. It seems like it ought to be possible to substitute through the refinement during inlining, but it doesn't seem to be straightforward due to the way that symbols are assigned to refinements and their members. At least, I couldn't figure out how to do it.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions