summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-03-12 15:38:33 +0000
committerMartin Odersky <odersky@gmail.com>2010-03-12 15:38:33 +0000
commit51850896c52db6ad7d31d0f9eb1c605e7e23b3e4 (patch)
tree81d5b2a645a08d0092c0de5ef9e8788f1f4fc0f5 /src
parent98a5d295396b9ce0d42f0ef1f82bcdb4fc3b5be9 (diff)
downloadscala-51850896c52db6ad7d31d0f9eb1c605e7e23b3e4.tar.gz
scala-51850896c52db6ad7d31d0f9eb1c605e7e23b3e4.tar.bz2
scala-51850896c52db6ad7d31d0f9eb1c605e7e23b3e4.zip
Closes #3143. Review by moors.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala34
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala34
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala7
3 files changed, 45 insertions, 30 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 50f62f3092..a068e93db0 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -84,14 +84,14 @@ trait Definitions extends reflect.generic.StandardDefinitions {
// the scala value classes
lazy val UnitClass = newClass(ScalaPackageClass, nme.Unit, anyvalparam).setFlag(ABSTRACT | FINAL)
- lazy val ByteClass = newValueClass(nme.Byte, 'B', 1)
- lazy val ShortClass = newValueClass(nme.Short, 'S', 2)
- lazy val CharClass = newValueClass(nme.Char, 'C', 2)
- lazy val IntClass = newValueClass(nme.Int, 'I', 3)
- lazy val LongClass = newValueClass(nme.Long, 'L', 4)
- lazy val FloatClass = newValueClass(nme.Float, 'F', 5)
- lazy val DoubleClass = newValueClass(nme.Double, 'D', 6)
- lazy val BooleanClass = newValueClass(nme.Boolean, 'Z', -1)
+ lazy val ByteClass = newValueClass(nme.Byte, 'B', 2)
+ lazy val ShortClass = newValueClass(nme.Short, 'S', 4)
+ lazy val CharClass = newValueClass(nme.Char, 'C', 3)
+ lazy val IntClass = newValueClass(nme.Int, 'I', 12)
+ lazy val LongClass = newValueClass(nme.Long, 'L', 24)
+ lazy val FloatClass = newValueClass(nme.Float, 'F', 48)
+ lazy val DoubleClass = newValueClass(nme.Double, 'D', 96)
+ lazy val BooleanClass = newValueClass(nme.Boolean, 'Z', 0)
def Boolean_and = getMember(BooleanClass, nme.ZAND)
def Boolean_or = getMember(BooleanClass, nme.ZOR)
@@ -582,9 +582,19 @@ trait Definitions extends reflect.generic.StandardDefinitions {
val refClass = new HashMap[Symbol, Symbol]
val abbrvTag = new HashMap[Symbol, Char]
- val numericWidth = new HashMap[Symbol, Int]
+ private val numericWeight = new HashMap[Symbol, Int]
+
+ def isNumericSubClass(sub: Symbol, sup: Symbol) =
+ numericWeight get sub match {
+ case Some(w1) =>
+ numericWeight get sup match {
+ case Some(w2) => w2 % w1 == 0
+ case None => false
+ }
+ case None => false
+ }
- private[symtab] def newValueClass(name: Name, tag: Char, width: Int): Symbol = {
+ private[symtab] def newValueClass(name: Name, tag: Char, weight: Int): Symbol = {
val boxedName = sn.Boxed(name)
val clazz = newClass(ScalaPackageClass, name, anyvalparam) setFlag (ABSTRACT | FINAL)
@@ -592,7 +602,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
boxedModule(clazz) = getModule(boxedName)
refClass(clazz) = getClass("scala.runtime." + name + "Ref")
abbrvTag(clazz) = tag
- if (width > 0) numericWidth(clazz) = width
+ if (weight > 0) numericWeight(clazz) = weight
val module = ScalaPackageClass.newModule(NoPosition, name)
ScalaPackageClass.info.decls.enter(module)
@@ -715,7 +725,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
/** Is symbol a numeric value class? */
def isNumericValueClass(sym: Symbol): Boolean =
- numericWidth contains sym
+ numericWeight contains sym
/** Is symbol a numeric value class? */
def isNumericValueType(tp: Type): Boolean = tp match {
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 665239a2a0..b1842176dd 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -2685,7 +2685,6 @@ A type's typeSymbol should never be inspected directly.
* as well as their instantiations.
*/
class TypeConstraint(lo0: List[Type], hi0: List[Type], numlo0: Type, numhi0: Type) {
- //var self: Type = _ //DEBUG
def this(lo0: List[Type], hi0: List[Type]) = this(lo0, hi0, NoType, NoType)
def this() = this(List(), List())
@@ -2706,7 +2705,8 @@ A type's typeSymbol should never be inspected directly.
def addLoBound(tp: Type, numBound: Boolean = false) {
if (numBound && isNumericValueType(tp)) {
- if (!isNumericSubType(tp, numlo)) numlo = tp
+ if (numlo == NoType || isNumericSubType(numlo, tp)) numlo = tp
+ else if (!isNumericSubType(tp, numlo)) numlo = IntClass.tpe
} else {
lobounds = tp :: lobounds
}
@@ -2714,7 +2714,8 @@ A type's typeSymbol should never be inspected directly.
def addHiBound(tp: Type, numBound: Boolean = false) {
if (numBound && isNumericValueType(tp)) {
- if (!isNumericSubType(numhi, tp)) numhi = tp
+ if (numhi == NoType || isNumericSubType(tp, numhi)) numhi = tp
+ else if (!isNumericSubType(numhi, tp)) numhi = intersectionType(List(ByteClass.tpe, CharClass.tpe), ScalaPackageClass)
} else {
hibounds = tp :: hibounds
}
@@ -4755,24 +4756,34 @@ A type's typeSymbol should never be inspected directly.
(annotationsLub(lub(ts map (_.withoutAnnotations)), ts), true)
else (lub(ts), false)
- def weakGlb(ts: List[Type]) =
- if (ts.nonEmpty && (ts forall isNumericValueType)) (numericGlb(ts), true)
- else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty)))
+ def weakGlb(ts: List[Type]) = {
+ if (ts.nonEmpty && (ts forall isNumericValueType)) {
+ val nglb = numericGlb(ts)
+ if (nglb != NoType) (nglb, true)
+ else (glb(ts), false)
+ } else if (ts.nonEmpty && (ts exists (_.annotations.nonEmpty))) {
(annotationsGlb(glb(ts map (_.withoutAnnotations)), ts), true)
- else (glb(ts), false)
+ } else (glb(ts), false)
+ }
def numericLub(ts: List[Type]) =
- (ByteClass.tpe /: ts) ((t1, t2) => if (isNumericSubType(t1, t2)) t2 else t1)
+ ts reduceLeft ((t1, t2) =>
+ if (isNumericSubType(t1, t2)) t2
+ else if (isNumericSubType(t2, t1)) t1
+ else IntClass.tpe)
def numericGlb(ts: List[Type]) =
- (DoubleClass.tpe /: ts) ((t1, t2) => if (isNumericSubType(t1, t2)) t1 else t2)
+ ts reduceLeft ((t1, t2) =>
+ if (isNumericSubType(t1, t2)) t1
+ else if (isNumericSubType(t2, t1)) t2
+ else NoType)
def isWeakSubType(tp1: Type, tp2: Type) =
tp1.deconst.normalize match {
case TypeRef(_, sym1, _) if isNumericValueClass(sym1) =>
tp2.deconst.normalize match {
case TypeRef(_, sym2, _) if isNumericValueClass(sym2) =>
- sym1 == sym2 || numericWidth(sym1) < numericWidth(sym2)
+ isNumericSubClass(sym1, sym2)
case tv2 @ TypeVar(_, _) =>
tv2.registerBound(tp1, isLowerBound = true, numBound = true)
case _ =>
@@ -4790,8 +4801,7 @@ A type's typeSymbol should never be inspected directly.
}
def isNumericSubType(tp1: Type, tp2: Type) =
- isNumericValueType(tp1) && isNumericValueType(tp2) &&
- (tp1.typeSymbol == tp2.typeSymbol || numericWidth(tp1.typeSymbol) < numericWidth(tp2.typeSymbol))
+ isNumericSubClass(tp1.typeSymbol, tp2.typeSymbol)
def lub(ts: List[Type]): Type = lub(ts, lubDepth(ts))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 1e498d406b..85d73896b0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -430,12 +430,7 @@ trait Infer {
else tp2 match {
case TypeRef(_, sym2, _) =>
if (sym2.isAliasType) isPlausiblySubType(tp1, tp2.dealias)
- else if (!sym2.isClass) true
- else if (sym1 isSubClass sym2) true
- else
- isNumericValueClass(sym1) &&
- isNumericValueClass(sym2) &&
- (sym1 == sym2 || numericWidth(sym1) < numericWidth(sym2))
+ else !sym2.isClass || (sym1 isSubClass sym2) || isNumericSubClass(sym1, sym2)
case _ =>
true
}