summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-09-19 16:19:56 +0200
committerPaul Phillips <paulp@improving.org>2012-09-20 09:41:34 -0700
commite171d6d969fe7ce0dd2fd7a7679d6edb08c7579c (patch)
treef54e7991ce2dcc601f65ed0191b4260d7e6b21ee /src
parentb94ae90110412e8af1e65230053c0e8aa26cd2d7 (diff)
downloadscala-e171d6d969fe7ce0dd2fd7a7679d6edb08c7579c.tar.gz
scala-e171d6d969fe7ce0dd2fd7a7679d6edb08c7579c.tar.bz2
scala-e171d6d969fe7ce0dd2fd7a7679d6edb08c7579c.zip
Value classes: eliminated half-boxing
We now apply erasure of value classes everywhere. previously, erasure was disabled in the value class itself. This led to irregegularities and bugs. See test run/valueclasses-pavlov.scala for something that led to a ClassCastException before.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala3
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala22
3 files changed, 21 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9381d6432e..072d823c60 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -429,6 +429,14 @@ abstract class Erasure extends AddInterfaces
|both have erased type ${afterPostErasure(bridge.tpe)}""".stripMargin)
}
for (bc <- root.baseClasses) {
+ if (settings.debug.value)
+ afterPostErasure(println(
+ s"""check bridge overrides in $bc
+ ${bc.info.nonPrivateDecl(bridge.name)}
+ ${site.memberType(bridge)}
+ ${site.memberType(bc.info.nonPrivateDecl(bridge.name) orElse IntClass)}
+ ${(bridge.matchingSymbol(bc, site))}""".stripMargin))
+
def overriddenBy(sym: Symbol) =
sym.matchingSymbol(bc, site).alternatives filter (sym => !sym.isBridge)
for (overBridge <- afterPostErasure(overriddenBy(bridge))) {
@@ -1046,7 +1054,7 @@ abstract class Erasure extends AddInterfaces
preEraseIsInstanceOf
} else if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) {
ApplyDynamic(qualifier, args) setSymbol fn.symbol setPos tree.pos
- } else if (fn.symbol.isMethodWithExtension) {
+ } else if (fn.symbol.isMethodWithExtension && !fn.symbol.tpe.isErroneous) {
Apply(gen.mkAttributedRef(extensionMethods.extensionMethod(fn.symbol)), qualifier :: args)
} else {
tree
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 0820d3e714..c72fd3681f 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -70,7 +70,8 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
val companionInfo = imeth.owner.companionModule.info
val candidates = extensionNames(imeth) map (companionInfo.decl(_))
val matching = candidates filter (alt => normalize(alt.tpe, imeth.owner) matches imeth.tpe)
- assert(matching.nonEmpty, "no extension method found for "+imeth+" among "+candidates+"/"+extensionNames(imeth))
+ assert(matching.nonEmpty,
+ s"no extension method found for $imeth:${imeth.tpe}+among ${candidates map (c => c.name+":"+c.tpe)} / ${extensionNames(imeth)}")
matching.head
}
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index cc5b5bb406..977398909f 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -203,28 +203,26 @@ trait Erasure {
def specialErasure(sym: Symbol)(tp: Type): Type =
if (sym != NoSymbol && sym.enclClass.isJavaDefined)
erasure(sym)(tp)
- else if (sym.isTerm && sym.owner.isDerivedValueClass)
- specialErasureAvoiding(sym.owner, tp)
- else if (sym.isValue && sym.owner.isMethodWithExtension)
- specialErasureAvoiding(sym.owner.owner, tp)
+ else if (sym.isClassConstructor)
+ specialConstructorErasure(sym.owner, tp)
else
specialScalaErasure(tp)
- def specialErasureAvoiding(clazz: Symbol, tpe: Type): Type = {
+ def specialConstructorErasure(clazz: Symbol, tpe: Type): Type = {
tpe match {
case PolyType(tparams, restpe) =>
- specialErasureAvoiding(clazz, restpe)
+ specialConstructorErasure(clazz, restpe)
case ExistentialType(tparams, restpe) =>
- specialErasureAvoiding(clazz, restpe)
+ specialConstructorErasure(clazz, restpe)
case mt @ MethodType(params, restpe) =>
MethodType(
- cloneSymbolsAndModify(params, specialErasureAvoiding(clazz, _)),
- if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
- else specialErasureAvoiding(clazz, (mt.resultType(mt.paramTypes))))
+ cloneSymbolsAndModify(params, specialScalaErasure),
+ specialConstructorErasure(clazz, restpe))
case TypeRef(pre, `clazz`, args) =>
typeRef(pre, clazz, List())
- case _ =>
- specialScalaErasure(tpe)
+ case tp =>
+ assert(clazz == ArrayClass || tp.isError, s"unexpected constructor erasure $tp for $clazz")
+ specialScalaErasure(tp)
}
}