summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/Types.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-05 15:01:07 -0800
committerPaul Phillips <paulp@improving.org>2012-01-05 21:07:55 -0800
commitcdd4aac9819bc6bb2872a503a1bb2542fcfb6230 (patch)
tree5b1c0d5fb25a4923b7aebc7a8c2a84d775c3cc24 /src/compiler/scala/reflect/internal/Types.scala
parent020053c3215579e8aeb871a4ad0078516994270d (diff)
downloadscala-cdd4aac9819bc6bb2872a503a1bb2542fcfb6230.tar.gz
scala-cdd4aac9819bc6bb2872a503a1bb2542fcfb6230.tar.bz2
scala-cdd4aac9819bc6bb2872a503a1bb2542fcfb6230.zip
Fix issue with higher-order type params.
I think I found an issue underlying more than one bit of sketchy behavior amongst CC[_] and friends. Plus, I managed to initialize TypeConstraints with the bounds of the originating type parameter. I feel like that should cause something nifty to happen somewhere, but I have seen neither confetti nor lasers in greater quantities than I usually do. Will keep my remaining eye out. Closes SI-5359, review by @moors.
Diffstat (limited to 'src/compiler/scala/reflect/internal/Types.scala')
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 5b4dc4b4c6..6b5ba05c6d 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -2451,9 +2451,29 @@ A type's typeSymbol should never be inspected directly.
*/
def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr))
def apply(origin: Type, constr: TypeConstraint) = new TypeVar(origin, constr, List(), List())
- // TODO why not initialise TypeConstraint with bounds of tparam?
- // @PP: I tried that, didn't work out so well for me.
- def apply(tparam: Symbol) = new TypeVar(tparam.tpeHK, new TypeConstraint, List(), tparam.typeParams)
+ // See pos/tcpoly_infer_implicit_tuple_wrapper for the test which
+ // fails if I initialize the type constraint with the type parameter
+ // bounds. It seems that in that instance it interferes with the
+ // inference. Thus, the isHigherOrderTypeParameter condition.
+ def apply(tparam: Symbol) = {
+ val constr = (
+ if (tparam.isAbstractType && tparam.typeParams.nonEmpty) {
+ // Force the info of a higher-order tparam's parameters.
+ // Otherwise things don't end well. See SI-5359.
+ val info = tparam.info
+ if (info.bounds exists (t => t.typeSymbol.isHigherOrderTypeParameter)) {
+ log("TVar(" + tparam + ") receives empty constraint due to higher order type parameter in bounds " + info.bounds)
+ new TypeConstraint
+ }
+ else {
+ log("TVar(" + tparam + ") constraint initialized with bounds " + info.bounds)
+ new TypeConstraint(info.bounds)
+ }
+ }
+ else new TypeConstraint
+ )
+ new TypeVar(tparam.tpeHK, constr, Nil, tparam.typeParams)
+ }
def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]) =
new TypeVar(origin, constr, args, params)
}
@@ -2495,10 +2515,9 @@ A type's typeSymbol should never be inspected directly.
override val typeArgs: List[Type],
override val params: List[Symbol]
) extends Type {
- private val numArgs = typeArgs.length
// params are needed to keep track of variance (see mapOverArgs in SubstMap)
- assert(typeArgs.isEmpty || sameLength(typeArgs, params))
- // var tid = { tidCount += 1; tidCount } //DEBUG
+ assert(typeArgs.isEmpty || sameLength(typeArgs, params),
+ "%s / params=%s / args=%s".format(origin, params, typeArgs))
/** The constraint associated with the variable */
var constr = constr0
@@ -2740,11 +2759,12 @@ A type's typeSymbol should never be inspected directly.
override def isVolatile = origin.isVolatile
private def levelString = if (settings.explaintypes.value) level else ""
- override def safeToString = constr.inst match {
- case null => "<null " + origin + ">"
- case NoType => "?" + levelString + origin + typeArgsString(this)
- case x => "" + x
- }
+ override def safeToString = (
+ if (constr eq null) "TVar<%s,constr=null>".format(origin)
+ else if (constr.inst eq null) "TVar<%s,constr.inst=null>".format(origin)
+ else if (constr.inst eq NoType) "?" + levelString + origin + typeArgsString(this)
+ else "" + constr.inst
+ )
override def kind = "TypeVar"
def cloneInternal = {
@@ -3248,6 +3268,7 @@ A type's typeSymbol should never be inspected directly.
*/
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(bounds: TypeBounds) = this(List(bounds.lo), List(bounds.hi))
def this() = this(List(), List())
private var lobounds = lo0
@@ -4159,7 +4180,7 @@ A type's typeSymbol should never be inspected directly.
case WildcardType =>
TypeVar(tp, new TypeConstraint)
case BoundedWildcardType(bounds) =>
- TypeVar(tp, new TypeConstraint(List(bounds.lo), List(bounds.hi)))
+ TypeVar(tp, new TypeConstraint(bounds))
case _ =>
mapOver(tp)
}