aboutsummaryrefslogblamecommitdiff
path: root/tests/pending/run/outertest.scala
blob: edeac9f62645e32c96af8bf07f927564f029f486 (plain) (tree)


































                                                                               
                                             

                





                                                





                            
                                                            










                                                                                  
// A test for the case where the outer field of class B#J should be eliminated.

import reflect.ClassTag

abstract class A {
  abstract class I

  val foo = this
}

class B extends A {
  class J extends I {
    val bar = foo
  }

  type II = I
  class K extends II {
    val bar = foo
  }

  class L extends (I @annotation.tailrec) {
    val bar = foo
  }
}


class C extends A {
  val c: C = this

  class M extends c.I {
    val bar = foo
  }
}


object Test extends dotty.runtime.LegacyApp {
  val b = new B
  val c0 = new C
  val c = new C {
// TODO NEEDS MANUAL CHANGE (early initializers)
// BEGIN copied early initializers
override val c = c0
// END copied early initializers
}

  assert((new b.J).bar eq b)
  assert((new b.K).bar eq b)
  assert((new b.L).bar eq b)
  assert((new c.M).bar eq c)

  def checkOuterFields[C: ClassTag](expected: Int): Unit = {
    val cls = implicitly[ClassTag[C]].runtimeClass
    val outerFields = cls.getDeclaredFields().filter(_.getName.contains("$outer"))
    assert(outerFields.size == expected, outerFields.map(_.getName))
  }

  checkOuterFields[A#I](1) // the base class must have the $outer pointer
  checkOuterFields[B#J](0) // reuse parent class' $outer pointer
  checkOuterFields[B#K](0) // ... through an alias
  checkOuterFields[B#L](0) // ... through the annotated type
  checkOuterFields[C#M](1) // different prefix, can't share.
}