summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-02-27 04:59:47 -0800
committerJames Iry <jamesiry@gmail.com>2013-02-28 06:55:32 -0800
commitbfd7863406146aa830028ed77f7b0107fc60e5dc (patch)
treed035580cd2941d0aca688e0f957189555dd8d84b /src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
parent4124a09379fe1784a6069f5af482bdabdb69a569 (diff)
downloadscala-bfd7863406146aa830028ed77f7b0107fc60e5dc.tar.gz
scala-bfd7863406146aa830028ed77f7b0107fc60e5dc.tar.bz2
scala-bfd7863406146aa830028ed77f7b0107fc60e5dc.zip
SI-7159 Distinguish between assignability and sub typing in TypeKinds
TypeKinds said SHORT <:< INT. But that's not quite true on the JVM. You can assign SHORT to INT, but you can't assign an ARRAY[SHORT] to ARRAY[INT]. Since JVM arrays are covariant it's clear that assignability and subtyping are distinct on the JVM. This commit adds an isAssignable method and moves the rules about the int sized primitives there. ICodeCheckers, ICodeReader, and GenICode are all updated to use isAssignable instead of <:<.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala32
1 files changed, 17 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 266e2b861f..1875c8c914 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -88,17 +88,20 @@ trait TypeKinds { self: ICodes =>
final def isNumericType: Boolean = isIntegralType | isRealType
/** Simple subtyping check */
- def <:<(other: TypeKind): Boolean = other match {
- // On the JVM, BOOL, BYTE, CHAR, SHORT need no coercion to INT
- // TODO it's pretty suspect to call this a subtyping relationship
- // for instance JVM Arrays are covariant, but Array[Char] is not
- // a subtype of Array[Int] on the JVM. However, when I attempted
- // to remove it I got verify errors when compiling the library
- // under -optimize
+ def <:<(other: TypeKind): Boolean
+
+ /**
+ * this is directly assignable to other if no coercion or
+ * casting is needed to convert this to other. It's a distinct
+ * relationship from <:< because on the JVM, BOOL, BYTE, CHAR,
+ * SHORT need no coercion to INT even though JVM arrays
+ * are covariant, ARRAY[SHORT] is not a subtype of ARRAY[INT]
+ */
+ final def isAssignabledTo(other: TypeKind): Boolean = other match {
case INT => this.isIntSizedType
- case _ => this eq other
+ case _ => this <:< other
}
-
+
/** Is this type a category 2 type in JVM terms? (ie, is it LONG or DOUBLE?) */
def isWideType: Boolean = false
@@ -117,6 +120,7 @@ trait TypeKinds { self: ICodes =>
override def toString = {
this.getClass.getName stripSuffix "$" dropWhile (_ != '$') drop 1
}
+ def <:<(other: TypeKind): Boolean = this eq other
}
/**
@@ -286,7 +290,7 @@ trait TypeKinds { self: ICodes =>
}
/** Checks subtyping relationship. */
- override def <:<(other: TypeKind) = isNothingType || (other match {
+ def <:<(other: TypeKind) = isNothingType || (other match {
case REFERENCE(cls2) => cls.tpe <:< cls2.tpe
case ARRAY(_) => cls == NullClass
case _ => false
@@ -324,7 +328,7 @@ trait TypeKinds { self: ICodes =>
/** Array subtyping is covariant, as in Java. Necessary for checking
* code that interacts with Java. */
- override def <:<(other: TypeKind) = other match {
+ def <:<(other: TypeKind) = other match {
case ARRAY(elem2) => elem <:< elem2
case REFERENCE(AnyRefClass | ObjectClass) => true // TODO: platform dependent!
case _ => false
@@ -342,7 +346,7 @@ trait TypeKinds { self: ICodes =>
}
/** Checks subtyping relationship. */
- override def <:<(other: TypeKind) = other match {
+ def <:<(other: TypeKind) = other match {
case BOXED(`kind`) => true
case REFERENCE(AnyRefClass | ObjectClass) => true // TODO: platform dependent!
case _ => false
@@ -355,6 +359,7 @@ trait TypeKinds { self: ICodes =>
*/
case object ConcatClass extends TypeKind {
override def toString = "ConcatClass"
+ def <:<(other: TypeKind): Boolean = this eq other
/**
* Approximate `lub`. The common type of two references is
@@ -365,9 +370,6 @@ trait TypeKinds { self: ICodes =>
case REFERENCE(_) => AnyRefReference
case _ => uncomparable(other)
}
-
- /** Checks subtyping relationship. */
- override def <:<(other: TypeKind) = this eq other
}
////////////////// Conversions //////////////////////////////