summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-01-11 20:08:47 +0000
committerPaul Phillips <paulp@improving.org>2011-01-11 20:08:47 +0000
commit566fefb05abe31e90f765d1fb0a89b264302d9ce (patch)
tree28be1b3d6c4b862ff9a24b6dd665cbb8df1b68a9 /src
parent5f40fe0456238a8c58d05e58cd61a960f9a107a7 (diff)
downloadscala-566fefb05abe31e90f765d1fb0a89b264302d9ce.tar.gz
scala-566fefb05abe31e90f765d1fb0a89b264302d9ce.tar.bz2
scala-566fefb05abe31e90f765d1fb0a89b264302d9ce.zip
In r22807 an optimization was added to remove B...
In r22807 an optimization was added to remove Box(Unbox(x)) combinations. It turns out that without this in place, an expression like "x".asInstanceOf[Int] will no longer throw an exception. Refined the optimization. Closes #4148, review by dragos.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala7
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala9
2 files changed, 12 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 0eb58e3ad2..26b4f88f0c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -629,6 +629,9 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val unboxMethod = new HashMap[Symbol, Symbol] // Type -> Method
val boxMethod = new HashMap[Symbol, Symbol] // Type -> Method
val primitiveCompanions = new mutable.HashSet[Symbol] // AnyVal -> Companion
+
+ lazy val boxedClassValues = boxedClass.values.toSet
+
/** Maps a companion object like scala.Int to scala.runtime.Int. */
lazy val runtimeCompanions = (primitiveCompanions map { sym =>
sym -> getModule("scala.runtime." + sym.name)
@@ -799,6 +802,10 @@ trait Definitions extends reflect.generic.StandardDefinitions {
def isValueClass(sym: Symbol): Boolean =
(sym eq UnitClass) || (boxedClass contains sym)
+ /** Is symbol a boxed value class, e.g. java.lang.Integer? */
+ def isBoxedValueClass(sym: Symbol): Boolean =
+ (sym eq BoxedUnitClass) || boxedClassValues(sym)
+
/** If symbol is a value class or a boxed value class, return the value class: otherwise NoSymbol. */
def unboxedValueClass(sym: Symbol): Symbol =
if (isValueClass(sym)) sym
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1df0b5bf3b..fa5f899da0 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -440,7 +440,6 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
/** The modifier typer which retypes with erased types. */
class Eraser(context: Context) extends Typer(context) {
-
/** Box `tree' of unboxed type */
private def box(tree: Tree): Tree = tree match {
case LabelDef(name, params, rhs) =>
@@ -454,9 +453,11 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
case x =>
assert(x != ArrayClass)
tree match {
- case Apply(boxFun, List(arg)) if (isUnbox(tree.symbol)) =>
- log("boxing an unbox: " + tree)
- log("replying with " + arg)
+ /** Can't always remove a Box(Unbox(x)) combination because the process of boxing x
+ * may lead to throwing an exception.
+ */
+ case Apply(boxFun, List(arg)) if isUnbox(tree.symbol) && isBoxedValueClass(arg.tpe.typeSymbol) =>
+ log("boxing an unbox: " + tree + " and replying with " + arg)
arg
case _ =>
(REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectClass.tpe