Skip to content

Crash when expanding value class extension method with annotation referencing this #14575

Open
@odersky

Description

@odersky

Compiler version

3.1.3 RC1

Minimized example

class ann(xs: Any) extends annotation.StaticAnnotation

class C

class D:
  def m: C = ???

trait Ops extends Any {
  def m: C @ann(this)
}

class Ops1(s: String) extends AnyVal with Ops:
  def a = new D
  def m = a.m

Output

Compiling with -Ycheck:all gives

exception while typing def m: C @ann(this) = Ops1.m$extension(this) of class class dotty.tools.dotc.ast.Trees$DefDef # -1
exception while typing @SourceFile("cc-anyval.scala") final class Ops1(s: String) extends AnyVal(), Ops
   {
  override def hashCode(): Int = Ops1.hashCode$extension(this)()
  override def equals(x$0: Any): Boolean = Ops1.equals$extension(this)(x$0)
  private val s: String
  def a: D = Ops1.a$extension(this)
  def m: C @ann(this) = Ops1.m$extension(this)
} of class class dotty.tools.dotc.ast.Trees$TypeDef # -1
exception while typing package <empty> {
  @SourceFile("cc-anyval.scala") class ann(xs: Any) extends 
    scala.annotation.Annotation
  (), annotation.StaticAnnotation {
    private[this] val xs: Any
  }
  @SourceFile("cc-anyval.scala") class C() extends Object() {}
  @SourceFile("cc-anyval.scala") class D() extends Object() {
    def m: C = ???
  }
  @SourceFile("cc-anyval.scala") trait Ops() extends Any {
    def m: C @ann(this)
  }
  @SourceFile("cc-anyval.scala") final class Ops1(s: String) extends AnyVal(), 
    Ops
   {
    override def hashCode(): Int = Ops1.hashCode$extension(this)()
    override def equals(x$0: Any): Boolean = Ops1.equals$extension(this)(x$0)
    private val s: String
    def a: D = Ops1.a$extension(this)
    def m: C @ann(this) = Ops1.m$extension(this)
  }
  final lazy module val Ops1: Ops1 = new Ops1()
  @SourceFile("cc-anyval.scala") final module class Ops1() extends AnyRef() {
    private def writeReplace(): AnyRef = 
      new scala.runtime.ModuleSerializationProxy(classOf[Ops1.type])
    final def hashCode$extension($this: Ops1)(): Int = $this.s.hashCode()
    final def equals$extension($this: Ops1)(x$0: Any): Boolean = 
      matchResult1[Boolean]: 
        {
          case val x1: (x$0 : Any) = x$0
          if x1.$isInstanceOf[Ops1 @unchecked] then 
            {
              case val x$0: Ops1 = x1.$asInstanceOf[Ops1 @unchecked]
              return[matchResult1] $this.s.==(x$0.s)
            }
           else ()
          return[matchResult1] false
        }
    final def a$extension($this: Ops1): D = new D()
    final def m$extension($this: Ops1): C @ann(this) = Ops1.a$extension($this).m
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # -1
*** error while checking cc-anyval.scala after phase patternMatcher ***
exception occurred while compiling cc-anyval.scala
java.lang.AssertionError: assertion failed: orphan param: $this.type, hash of binder = 81269359, tree = <empty>, type = AnnotatedType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class C),ConcreteAnnotation(Apply(Select(New(Ident(ann)),<init>),List(This(Ident()))))) while compiling cc-anyval.scala
Exception in thread "main" java.lang.AssertionError: assertion failed: orphan param: $this.type, hash of binder = 81269359, tree = <empty>, type = AnnotatedType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class C),ConcreteAnnotation(Apply(Select(New(Ident(ann)),<init>),List(This(Ident())))))
	at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
	at dotty.tools.dotc.transform.TreeChecker$$anon$2.apply(TreeChecker.scala:640)

I verified that the tree goes in fact wrong after miniphase ExtensionMethods.

Expectation

Successful compile

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions