diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 29 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 1 | ||||
-rw-r--r-- | test/files/pos/t6278-synth-def.scala | 30 | ||||
-rw-r--r-- | test/files/run/getClassTest-valueClass.check | 2 | ||||
-rw-r--r-- | test/files/run/getClassTest-valueClass.scala | 10 |
7 files changed, 53 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index d97fbf5daa..bfede7a690 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -326,7 +326,7 @@ abstract class Erasure extends AddInterfaces } // Methods on Any/Object which we rewrite here while we still know what // is a primitive and what arrived boxed. - private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass) ++ ( + private lazy val interceptedMethods = Set[Symbol](Any_##, Object_##, Any_getClass, AnyVal_getClass) ++ ( // Each value class has its own getClass for ultra-precise class object typing. ScalaValueClasses map (_.tpe member nme.getClass_) ) @@ -1069,9 +1069,11 @@ abstract class Erasure extends AddInterfaces case _ => global.typer.typed(gen.mkRuntimeCall(nme.hash_, List(qual))) } - } else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) { + } else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) { // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen)))) + } else if (fn.symbol == AnyVal_getClass) { + tree setSymbol Object_getClass } else { tree } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 21d61ff7b1..d055c6ec48 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2743,12 +2743,18 @@ trait Typers extends Modes with Adaptations with Tags { // this code by associating defaults and companion objects // with the original tree instead of the new symbol. def matches(stat: Tree, synt: Tree) = (stat, synt) match { + // synt is default arg for stat case (DefDef(_, statName, _, _, _, _), DefDef(mods, syntName, _, _, _, _)) => mods.hasDefaultFlag && syntName.toString.startsWith(statName.toString) + // synt is companion module case (ClassDef(_, className, _, _), ModuleDef(_, moduleName, _)) => className.toTermName == moduleName + // synt is implicit def for implicit class (#6278) + case (ClassDef(cmods, cname, _, _), DefDef(dmods, dname, _, _, _, _)) => + cmods.isImplicit && dmods.isImplicit && cname.toTermName == dname + case _ => false } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index e5f5e9dc5d..a8635151ff 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -167,35 +167,6 @@ object ScalaRunTime { def checkInitialized[T <: AnyRef](x: T): T = if (x == null) throw new UninitializedError else x - abstract class Try[+A] { - def Catch[B >: A](handler: PartialFunction[Throwable, B]): B - def Finally(fin: => Unit): A - } - - def Try[A](block: => A): Try[A] = new Try[A] with Runnable { - private var result: A = _ - private var exception: Throwable = - try { run() ; null } - catch { - case e: ControlThrowable => throw e // don't catch non-local returns etc - case e: Throwable => e - } - - def run() { result = block } - - def Catch[B >: A](handler: PartialFunction[Throwable, B]): B = - if (exception == null) result - else if (handler isDefinedAt exception) handler(exception) - else throw exception - - def Finally(fin: => Unit): A = { - fin - - if (exception == null) result - else throw exception - } - } - def _toString(x: Product): String = x.productIterator.mkString(x.productPrefix + "(", ",", ")") diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index c21ebfe997..4e44b76607 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -277,6 +277,7 @@ trait Definitions extends api.StandardDefinitions { anyval }).asInstanceOf[ClassSymbol] lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor + def AnyVal_getClass = getMemberMethod(AnyValClass, nme.getClass_) // bottom types lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing) diff --git a/test/files/pos/t6278-synth-def.scala b/test/files/pos/t6278-synth-def.scala new file mode 100644 index 0000000000..b8b660fbe3 --- /dev/null +++ b/test/files/pos/t6278-synth-def.scala @@ -0,0 +1,30 @@ + +package t6278 + +import language.implicitConversions + +object test { + def ok() { + class Foo(val i: Int) { + def foo[A](body: =>A): A = body + } + implicit def toFoo(i: Int): Foo = new Foo(i) + + val k = 1 + k foo println("k?") + val j = 2 + } + def nope() { + implicit class Foo(val i: Int) { + def foo[A](body: =>A): A = body + } + + val k = 1 + k foo println("k?") + //lazy + val j = 2 + } + def main(args: Array[String]) { + ok(); nope() + } +} diff --git a/test/files/run/getClassTest-valueClass.check b/test/files/run/getClassTest-valueClass.check new file mode 100644 index 0000000000..7608d92b4e --- /dev/null +++ b/test/files/run/getClassTest-valueClass.check @@ -0,0 +1,2 @@ +int +class V diff --git a/test/files/run/getClassTest-valueClass.scala b/test/files/run/getClassTest-valueClass.scala new file mode 100644 index 0000000000..05a116dfff --- /dev/null +++ b/test/files/run/getClassTest-valueClass.scala @@ -0,0 +1,10 @@ +class V(val x: Int) extends AnyVal + +object Test { + def main(args: Array[String]) = { + val v = new V(2) + val s: Any = 2 + println(2.getClass) + println(v.getClass) + } +} |