diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2017-01-10 14:17:21 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-10 14:17:21 -0800 |
commit | fac487e397c36395ee91c3b725aad6a8050cc0ad (patch) | |
tree | f38a346f4ddac93208db2dfa628c22bf4a484f46 /src | |
parent | 32a746103762bd4d9c21ef7513edc334e77c1f57 (diff) | |
parent | 8138e24bbdccacdfee9873c5a0e21afaf78c6369 (diff) | |
download | scala-fac487e397c36395ee91c3b725aad6a8050cc0ad.tar.gz scala-fac487e397c36395ee91c3b725aad6a8050cc0ad.tar.bz2 scala-fac487e397c36395ee91c3b725aad6a8050cc0ad.zip |
Merge pull request #5633 from adriaanm/ticket/9331
SI-9331 Fix canEqual for case classes with HK type params
Diffstat (limited to 'src')
3 files changed, 11 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 99e61d2482..9b73f203e0 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -676,10 +676,9 @@ abstract class ClassfileParser { // so have to check unsafeTypeParams.isEmpty before worrying about raw type case below, // or we'll create a boatload of needless existentials. else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp - else debuglogResult(s"raw type from $classSym"){ + else debuglogResult(s"raw type from $classSym") { // raw type - existentially quantify all type parameters - val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) - newExistentialType(eparams, typeRef(pre, classSym, eparams.map(_.tpeHK))) + classExistentialType(pre, classSym) } case tp => assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp") diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 1b3f066fc1..9cc0fc4c59 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -143,8 +143,9 @@ trait SyntheticMethods extends ast.TreeDSL { */ def canEqualMethod: Tree = { syntheticCanEqual = true - createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe)(m => - Ident(m.firstParam) IS_OBJ classExistentialType(clazz)) + createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe) { m => + Ident(m.firstParam) IS_OBJ classExistentialType(context.prefix, clazz) + } } /* that match { case _: this.C => true ; case _ => false } 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 |