diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 34 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 34 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 7 |
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 } |