diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:28:58 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2011-10-20 22:28:58 +0000 |
commit | 8704ed2fc92e3d82287317fe34126c5d4d84e10c (patch) | |
tree | 035a6d98a08e102ac6116e9048c36996d1af6a22 /src/compiler/scala/reflect/internal/Types.scala | |
parent | 98b904db879a0b987d6ae50e5d5d990285ed8c59 (diff) | |
download | scala-8704ed2fc92e3d82287317fe34126c5d4d84e10c.tar.gz scala-8704ed2fc92e3d82287317fe34126c5d4d84e10c.tar.bz2 scala-8704ed2fc92e3d82287317fe34126c5d4d84e10c.zip |
infer singleton when asking for it
a type var's constraint now also tracks whether the type var was
compared to a stable type
if it was, we probably shouldn't widen the type argument that's inferred
for this var, as the result will surely fail to type check
NOTE: must be enabled using -Xexperimental
review by extempore
Diffstat (limited to 'src/compiler/scala/reflect/internal/Types.scala')
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 24b641ddb4..a0bd994a97 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -2338,6 +2338,20 @@ A type's typeSymbol should never be inspected directly. //private var tidCount = 0 //DEBUG + object HasTypeMember { + def apply(name: TypeName, tp: Type): Type = { + val bound = refinedType(List(WildcardType), NoSymbol) + val bsym = bound.typeSymbol.newAliasType(NoPosition, name) + bsym setInfo tp + bound.decls enter bsym + bound + } + def unapply(tp: Type): Option[(TypeName, Type)] = tp match { + case RefinedType(List(WildcardType), Scope(sym)) => Some((sym.name.toTypeName, sym.info)) + case _ => None + } + } + //@M // a TypeVar used to be a case class with only an origin and a constr // then, constr became mutable (to support UndoLog, I guess), @@ -2558,6 +2572,8 @@ A type's typeSymbol should never be inspected directly. // So the strategy used here is to test first the type, then the direct parents, and finally // to fall back on the individual base types. This warrants eventual re-examination. + // AM: I think we could use the `suspended` flag to avoid side-effecting during unification + if (suspended) // constraint accumulation is disabled checkSubtype(tp, origin) else if (constr.instValid) // type var is already set @@ -2603,11 +2619,7 @@ A type's typeSymbol should never be inspected directly. * (`T` corresponds to @param sym) */ def registerTypeSelection(sym: Symbol, tp: Type): Boolean = { - val bound = refinedType(List(WildcardType), NoSymbol) - val bsym = bound.typeSymbol.newAliasType(NoPosition, sym.name.toTypeName) - bsym setInfo tp - bound.decls enter bsym - registerBound(bound, false) + registerBound(HasTypeMember(sym.name.toTypeName, tp), false) } /** Can this variable be related in a constraint to type `tp`? @@ -3206,7 +3218,7 @@ A type's typeSymbol should never be inspected directly. /** A class expressing upper and lower bounds constraints of type variables, * as well as their instantiations. */ - class TypeConstraint(lo0: List[Type], hi0: List[Type], numlo0: Type, numhi0: Type) { + class TypeConstraint(lo0: List[Type], hi0: List[Type], numlo0: Type, numhi0: Type, avoidWidening0: Boolean = false) { def this(lo0: List[Type], hi0: List[Type]) = this(lo0, hi0, NoType, NoType) def this() = this(List(), List()) @@ -3214,9 +3226,11 @@ A type's typeSymbol should never be inspected directly. private var hibounds = hi0 private var numlo = numlo0 private var numhi = numhi0 + private var avoidWidening = avoidWidening0 def loBounds: List[Type] = if (numlo == NoType) lobounds else numlo :: lobounds def hiBounds: List[Type] = if (numhi == NoType) hibounds else numhi :: hibounds + def avoidWiden: Boolean = avoidWidening def addLoBound(tp: Type, isNumericBound: Boolean = false) { if (isNumericBound && isNumericValueType(tp)) { @@ -3228,7 +3242,16 @@ A type's typeSymbol should never be inspected directly. else lobounds ::= tp } + def checkWidening(tp: Type) { + if(tp.isStable) avoidWidening = true + else tp match { + case HasTypeMember(_, _) => avoidWidening = true + case _ => + } + } + def addHiBound(tp: Type, isNumericBound: Boolean = false) { + checkWidening(tp) if (isNumericBound && isNumericValueType(tp)) { if (numhi == NoType || isNumericSubType(tp, numhi)) numhi = tp @@ -3249,7 +3272,7 @@ A type's typeSymbol should never be inspected directly. def instValid = (inst ne null) && (inst ne NoType) def cloneInternal = { - val tc = new TypeConstraint(lobounds, hibounds, numlo, numhi) + val tc = new TypeConstraint(lobounds, hibounds, numlo, numhi, avoidWidening) tc.inst = inst tc } |