From 8138e24bbdccacdfee9873c5a0e21afaf78c6369 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 27 May 2015 14:29:51 +1000 Subject: SI-9331 Fix canEqual for case classes with HK type params Time for the courage of our convictions: follow the advice of my TODO comment from SI-8244 / f62e280825 and fix `classExistentialType` once and for all. This is the change in the generated `canEquals` method in the test case; we no longer get a kind conformance error. ``` --- sandbox/old.log 2015-05-27 14:31:27.000000000 +1000 +++ sandbox/new.log 2015-05-27 14:31:29.000000000 +1000 @@ -15,7 +15,7 @@ case _ => throw new IndexOutOfBoundsException(x$1.toString()) }; override def productIterator: Iterator[Any] = runtime.this.ScalaRunTime.typedProductIterator[Any](Stuff.this); - def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[Stuff[Proxy[PP]]](); + def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[Stuff[_ <: [PP]Proxy[PP]]](); override def hashCode(): Int = ScalaRunTime.this._hashCode(Stuff.this); override def toString(): String = ScalaRunTime.this._toString(Stuff.this); override def equals(x$1: Any): Boolean = x$1 match { @@ -38,9 +38,3 @@ } } ``` I also heeded my own advice to pass in a prefix to this method. --- src/reflect/scala/reflect/internal/Definitions.scala | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/reflect/scala/reflect') diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 0bdf5b4647..69cdf5f04e 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -646,8 +646,8 @@ trait Definitions extends api.StandardDefinitions { isBundle && isBlackbox } - def isListType(tp: Type) = tp <:< classExistentialType(ListClass) - def isIterableType(tp: Type) = tp <:< classExistentialType(IterableClass) + def isListType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(ListClass) + def isIterableType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(IterableClass) // These "direct" calls perform no dealiasing. They are most needed when // printing types when one wants to preserve the true nature of the type. @@ -925,14 +925,10 @@ trait Definitions extends api.StandardDefinitions { * * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }. */ - // TODO Review the way this is used. I see two potential problems: - // 1. `existentialAbstraction` here doesn't create fresh existential type symbols, it just - // uses the class type parameter symbols directly as the list of quantified symbols. - // See SI-8244 for the trouble that this can cause. - // Compare with callers of `typeParamsToExistentials` (used in Java raw type handling) - // 2. Why don't we require a prefix? Could its omission lead to wrong results in CheckabilityChecker? - def classExistentialType(clazz: Symbol): Type = - existentialAbstraction(clazz.typeParams, clazz.tpe_*) + def classExistentialType(prefix: Type, clazz: Symbol): Type = { + val eparams = typeParamsToExistentials(clazz, clazz.unsafeTypeParams) + newExistentialType(eparams, typeRef(prefix, clazz, eparams.map(_.tpeHK))) + } // members of class scala.Any -- cgit v1.2.3