diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/PostErasure.scala | 61 | ||||
-rw-r--r-- | test/files/neg/anytrait.check | 7 | ||||
-rw-r--r-- | test/files/neg/anytrait.scala | 10 | ||||
-rw-r--r-- | test/files/run/Meter.check | 7 |
4 files changed, 85 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala new file mode 100644 index 0000000000..1efa9ef3d5 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -0,0 +1,61 @@ +package scala.tools.nsc +package transform + +trait PostErasure extends InfoTransform with TypingTransformers { + + val global: Global + import global._ + import definitions._ + + val phaseName: String = "posterasure" + + def newTransformer(unit: CompilationUnit): Transformer = new PostErasureTransformer(unit) + override def changesBaseClasses = false + + object elimErasedInline extends TypeMap { + def apply(tp: Type) = tp match { + case ErasedInlineType(clazz) => erasure.valueClassErasure(clazz) + case _ => mapOver(tp) + } + } + + def transformInfo(sym: Symbol, tp: Type) = elimErasedInline(tp) + + class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + + override def transform(tree: Tree) = + super.transform(tree) setType elimErasedInline(tree.tpe) match { + case // new C(arg).underlying ==> arg + Apply(sel @ Select( + Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)), + acc), List()) + if atPhase(currentRun.erasurePhase) { + tpt.tpe.typeSymbol.isInlineClass && + sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor + } => + if (settings.debug.value) log("Removing "+tree+" -> "+arg) + arg + case // new C(arg1) == new C(arg2) ==> arg1 == arg2 + Apply(sel @ Select( + Apply(Select(New(tpt1), nme.CONSTRUCTOR), List(arg1)), + cmp), + List(Apply(Select(New(tpt2), nme.CONSTRUCTOR), List(arg2)))) + if atPhase(currentRun.erasurePhase) { + tpt1.tpe.typeSymbol.isInlineClass && + (cmp == nme.EQ || cmp == nme.NE) && + tpt2.tpe.typeSymbol == tpt1.tpe.typeSymbol + } => + val result = Apply(Select(arg1, cmp) setPos sel.pos, List(arg2)) setPos tree.pos + log("shortcircuiting equality "+tree+" -> "+result) + localTyper.typed(result) + + case // arg.asInstanceOf[T] ==> arg if arg.tpe == T + Apply(TypeApply(cast @ Select(arg, asinstanceof), List(tpt)), List()) + if cast.symbol == Object_asInstanceOf && arg.tpe =:= tpt.tpe => // !!! <:< ? + if (settings.debug.value) log("Shortening "+tree+" -> "+arg) + arg + case tree1 => + tree1 + } + } +}
\ No newline at end of file diff --git a/test/files/neg/anytrait.check b/test/files/neg/anytrait.check new file mode 100644 index 0000000000..99c24b85a0 --- /dev/null +++ b/test/files/neg/anytrait.check @@ -0,0 +1,7 @@ +anytrait.scala:3: error: this statement is not allowed in trait extending from class Any: private[this] var x: Int = 1 + var x = 1 + ^ +anytrait.scala:5: error: this statement is not allowed in trait extending from class Any: T.this.x_=(T.this.x.+(1)) + { x += 1 } + ^ +two errors found diff --git a/test/files/neg/anytrait.scala b/test/files/neg/anytrait.scala new file mode 100644 index 0000000000..1501486105 --- /dev/null +++ b/test/files/neg/anytrait.scala @@ -0,0 +1,10 @@ +trait T extends Any { + + var x = 1 + + { x += 1 } + + type T = Int + + val y: T +} diff --git a/test/files/run/Meter.check b/test/files/run/Meter.check new file mode 100644 index 0000000000..a936073489 --- /dev/null +++ b/test/files/run/Meter.check @@ -0,0 +1,7 @@ +2.0 +4.0m +false +x.hashCode: 1072693248 +x == 1: false +x == y: true +a == b: true |