summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2008-02-06 18:02:39 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2008-02-06 18:02:39 +0000
commit11d8e2c4870d13be7b4a651495aae8fb8946d60f (patch)
tree6e6f0534d1fd9edb843de85adec93425481879de /src
parent9b379d01bf4c1653d015d70aee8df71be8a6904e (diff)
downloadscala-11d8e2c4870d13be7b4a651495aae8fb8946d60f.tar.gz
scala-11d8e2c4870d13be7b4a651495aae8fb8946d60f.tar.bz2
scala-11d8e2c4870d13be7b4a651495aae8fb8946d60f.zip
Partial fix to #397.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala10
-rw-r--r--src/library/scala/runtime/BoxesUtility.java168
-rw-r--r--src/library/scala/runtime/Comparator.java80
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala7
5 files changed, 15 insertions, 251 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index f3953792f3..bb582faba1 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -260,6 +260,7 @@ trait StdNames {
val booleanValue = newTermName("booleanValue")
val box = newTermName("box")
val boxArray = newTermName("boxArray")
+ val forceBoxedArray = newTermName("forceBoxedArray")
val checkInitialized = newTermName("checkInitialized")
val classOf = newTermName("classOf")
val coerce = newTermName("coerce")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b1088dd599..1969880022 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -746,16 +746,20 @@ trait Typers { self: Analyzer =>
assert((mode & HKmode) == 0) //@M
instantiate(tree, mode, pt)
} else if (tree.tpe <:< pt) {
- def isStructuralType(tpe: Type) = tpe match {
+ def isStructuralType(tpe: Type): Boolean = tpe match {
case RefinedType(ps, decls) =>
decls.toList exists (x => x.isTerm && x.allOverriddenSymbols.isEmpty)
case _ =>
false
}
if (isStructuralType(pt) && tree.tpe.typeSymbol == ArrayClass) {
- println("need to insert box for "+tree)
+ // all Arrays used as structural refinement typed values must be boxed
+ // this does not solve the case where the type to be adapted to comes
+ // from a type variable that was bound by a strctural but is instantiated
+ typed(Apply(Select(gen.mkAttributedRef(ScalaRunTimeModule), nme.forceBoxedArray), List(tree)))
}
- tree
+ else
+ tree
} else {
if ((mode & PATTERNmode) != 0) {
if ((tree.symbol ne null) && tree.symbol.isModule)
diff --git a/src/library/scala/runtime/BoxesUtility.java b/src/library/scala/runtime/BoxesUtility.java
deleted file mode 100644
index bf065e7dbe..0000000000
--- a/src/library/scala/runtime/BoxesUtility.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-/**
- * @author Gilles Dubochet
- * @version 1.0
- */
-public class BoxesUtility {
-
- private static int charLowBound = 0;
- private static int charUpBound = 255;
- private static Character[] charCache = new Character[charUpBound - charLowBound + 1];
-
- private static int byteLowBound = -128;
- private static int byteUpBound = 127;
- private static Byte[] byteCache = new Byte[byteUpBound - byteLowBound + 1];
-
- private static int shortLowBound = -128;
- private static int shortUpBound = 127;
- private static Short[] shortCache = new Short[shortUpBound - shortLowBound + 1];
-
- private static int intLowBound = -128;
- private static int intUpBound = 1024;
- private static Integer[] intCache = new Integer[intUpBound - intLowBound + 1];
-
- private static int longLowBound = -128;
- private static int longUpBound = 1024;
- private static Long[] longCache = new Long[longUpBound - longLowBound + 1];
-
- static {
- int idx = 0;
- while (idx <= charUpBound - charLowBound) {
- charCache[idx] = new Character((char)(idx + charLowBound));
- idx = idx + 1;
- }
- idx = 0;
- while (idx <= byteUpBound - byteLowBound) {
- byteCache[idx] = new Byte((byte)(idx + byteLowBound));
- idx = idx + 1;
- }
- idx = 0;
- while (idx <= shortUpBound - shortLowBound) {
- shortCache[idx] = new Short((short)(idx + shortLowBound));
- idx = idx + 1;
- }
- idx = 0;
- while (idx <= intUpBound - intLowBound) {
- intCache[idx] = new Integer((int)(idx + intLowBound));
- idx = idx + 1;
- }
- idx = 0;
- while (idx <= longUpBound - longLowBound) {
- longCache[idx] = new Long((long)(idx + longLowBound));
- idx = idx + 1;
- }
- }
-
- public static Boolean boxToBoolean(boolean b) {
- return b ? Boolean.TRUE : Boolean.FALSE;
- }
-
- public static Character boxToCharacter(char c) {
- if (c >= charLowBound && c <= charUpBound)
- return charCache[(int)c - charLowBound];
- else
- return new Character(c);
- }
-
- public static Byte boxToByte(byte b) {
- if (b >= byteLowBound && b <= byteUpBound)
- return byteCache[(int)b - byteLowBound];
- else
- return new Byte(b);
- }
-
- public static Short boxToShort(short s) {
- if (s >= shortLowBound && s <= shortUpBound)
- return shortCache[(int)s - shortLowBound];
- else
- return new Short(s);
- }
-
- public static Integer boxToInteger(int i) {
- if (i >= intLowBound && i <= intUpBound)
- return intCache[(int)i - intLowBound];
- else
- return new Integer(i);
- }
-
- public static Long boxToLong(long l) {
- if (l >= longLowBound && l <= longUpBound)
- return longCache[(int)l - longLowBound];
- else
- return new Long(l);
- }
-
- public static Float boxToFloat(float f) {
- return new Float(f);
- }
-
- public static Double boxToDouble(double d) {
- return new Double(d);
- }
-
- public static boolean unboxToBoolean(Object b) {
- return b == null ? false : ((Boolean)b).booleanValue();
- }
-
- public static char unboxToChar(Object c) {
- if (c == null)
- return 0;
- else
- return ((Character)c).charValue();
- }
-
- public static byte unboxToByte(Object b) {
- if (b == null)
- return 0;
- else
- return ((Byte)b).byteValue();
- }
-
- public static short unboxToShort(Object s) {
- if (s == null)
- return 0;
- else
- return ((Short)s).shortValue();
- }
-
- public static int unboxToInt(Object i) {
- if (i == null)
- return 0;
- else
- return ((Integer)i).intValue();
- }
-
- public static long unboxToLong(Object l) {
- if (l == null)
- return 0;
- else
- return ((Long)l).longValue();
- }
-
- public static float unboxToFloat(Object f) {
- if (f == null)
- return 0.0f;
- else
- return ((Float)f).floatValue();
- }
-
- public static double unboxToDouble(Object d) {
- if (d == null)
- return 0.0;
- else
- return ((Double)d).doubleValue();
- }
-
-}
diff --git a/src/library/scala/runtime/Comparator.java b/src/library/scala/runtime/Comparator.java
deleted file mode 100644
index cd4303c79f..0000000000
--- a/src/library/scala/runtime/Comparator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.runtime;
-
-/** An object (static class) providing a correct notion of equality in
- * the general case, in particular with boxed values.
- *
- * @author Gilles Dubochet
- * @author Martin Odersky
- * @contributor Stepan Koltsov
- * @version 1.2
- */
-public class Comparator {
-
- private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
-
- private static int typeCode(Object a) {
- if (a instanceof Integer) return INT;
- if (a instanceof Character) return CHAR;
- if (a instanceof Long) return LONG;
- if (a instanceof Double) return DOUBLE;
- if (a instanceof Float) return FLOAT;
- if (a instanceof Byte) return BYTE;
- if (a instanceof Short) return SHORT;
- return OTHER;
- }
-
- /** A rich implementation of the <code>equals</code> method that overrides the
- * default equals because Java's boxed primitives are utterly broken. This equals
- * is inserted instead of a normal equals by the Scala compiler (in the
- * ICode phase, method <code>genEqEqPrimitive</code>) only when either
- * side of the comparison is a subclass of <code>AnyVal</code>, of
- * <code>java.lang.Number</code>, of <code>java.lang.Character</code> or
- * is exactly <code>Any</code> or <code>AnyRef</code>.
- */
- public static boolean equals(Object a, Object b) {
- if (a == null || b == null)
- return a == b;
- else if (a.equals(b))
- return true;
- else if (a instanceof Number || a instanceof Character || b instanceof Number || b instanceof Character) {
- int acode = typeCode(a);
- int bcode = typeCode(b);
- int maxcode = (acode < bcode) ? bcode : acode;
- if (maxcode <= INT) {
- int aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).intValue();
- int bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).intValue();
- return aa == bb;
- }
- else if (maxcode <= LONG) {
- long aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).longValue();
- long bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).longValue();
- return aa == bb;
- }
- else if (maxcode <= FLOAT) {
- float aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).floatValue();
- float bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).floatValue();
- return aa == bb;
- }
- else if (maxcode <= DOUBLE) {
- double aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).doubleValue();
- double bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).doubleValue();
- return aa == bb;
- }
- else
- return b.equals(a);
- }
- else
- return false;
- }
-}
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index d7a0776f36..a44046985d 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -32,6 +32,13 @@ object ScalaRunTime {
def isValueTag(tag: String) = tag.charAt(0) == '.'
def isValueClass(clazz: Class[_]) = clazz.isPrimitive()
+ def forceBoxedArray[A <: Any](xs: Seq[A]): Array[A] = {
+ val array = new Array[A](xs.length)
+ var i = 0
+ for (x <- xs.elements) { array(i) = x; i += 1 }
+ array
+ }
+
def checkInitialized[T <: AnyRef](x: T): T =
if (x == null) throw new UninitializedError else x