summaryrefslogblamecommitdiff
path: root/test/files/run/outertest.scala
blob: fa0443f66948734474e67a1b84a990e6c37f31c9 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                               


                       
                  
                  
 

                
 


                     

   



                      
 


                                           

 
 



                       

                 

 
 
                         
               












                                                                                  
 




                                                                         
 
// 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 App {
  val b = new B
  val c0 = new C
  val c = new { override val c = c0 } with C

  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) {
    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.
}