Skip to content

Commit fac487e

Browse files
authored
Merge pull request scala#5633 from adriaanm/ticket/9331
SI-9331 Fix canEqual for case classes with HK type params
2 parents 32a7461 + 8138e24 commit fac487e

File tree

6 files changed

+52
-50
lines changed

6 files changed

+52
-50
lines changed

src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -676,10 +676,9 @@ abstract class ClassfileParser {
676676
// so have to check unsafeTypeParams.isEmpty before worrying about raw type case below,
677677
// or we'll create a boatload of needless existentials.
678678
else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp
679-
else debuglogResult(s"raw type from $classSym"){
679+
else debuglogResult(s"raw type from $classSym") {
680680
// raw type - existentially quantify all type parameters
681-
val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams)
682-
newExistentialType(eparams, typeRef(pre, classSym, eparams.map(_.tpeHK)))
681+
classExistentialType(pre, classSym)
683682
}
684683
case tp =>
685684
assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")

src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ trait SyntheticMethods extends ast.TreeDSL {
143143
*/
144144
def canEqualMethod: Tree = {
145145
syntheticCanEqual = true
146-
createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe)(m =>
147-
Ident(m.firstParam) IS_OBJ classExistentialType(clazz))
146+
createMethod(nme.canEqual_, List(AnyTpe), BooleanTpe) { m =>
147+
Ident(m.firstParam) IS_OBJ classExistentialType(context.prefix, clazz)
148+
}
148149
}
149150

150151
/* that match { case _: this.C => true ; case _ => false }

src/reflect/scala/reflect/internal/Definitions.scala

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ trait Definitions extends api.StandardDefinitions {
646646
isBundle && isBlackbox
647647
}
648648

649-
def isListType(tp: Type) = tp <:< classExistentialType(ListClass)
650-
def isIterableType(tp: Type) = tp <:< classExistentialType(IterableClass)
649+
def isListType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(ListClass)
650+
def isIterableType(tp: Type) = tp.typeSymbol.isNonBottomSubClass(IterableClass)
651651

652652
// These "direct" calls perform no dealiasing. They are most needed when
653653
// printing types when one wants to preserve the true nature of the type.
@@ -925,14 +925,10 @@ trait Definitions extends api.StandardDefinitions {
925925
*
926926
* C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }.
927927
*/
928-
// TODO Review the way this is used. I see two potential problems:
929-
// 1. `existentialAbstraction` here doesn't create fresh existential type symbols, it just
930-
// uses the class type parameter symbols directly as the list of quantified symbols.
931-
// See SI-8244 for the trouble that this can cause.
932-
// Compare with callers of `typeParamsToExistentials` (used in Java raw type handling)
933-
// 2. Why don't we require a prefix? Could its omission lead to wrong results in CheckabilityChecker?
934-
def classExistentialType(clazz: Symbol): Type =
935-
existentialAbstraction(clazz.typeParams, clazz.tpe_*)
928+
def classExistentialType(prefix: Type, clazz: Symbol): Type = {
929+
val eparams = typeParamsToExistentials(clazz, clazz.unsafeTypeParams)
930+
newExistentialType(eparams, typeRef(prefix, clazz, eparams.map(_.tpeHK)))
931+
}
936932

937933
// members of class scala.Any
938934

test/files/pos/t9331.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.language.higherKinds
2+
3+
trait Proxy[+T]
4+
case class Stuff[+P[PP] <: Proxy[PP]]() {
5+
// canEqual was incorrectly synthetized and started reporting a kind error.
6+
}

test/files/run/existentials-in-compiler.check

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ abstract trait Bippy[A <: AnyRef, B] extends AnyRef
22
extest.Bippy[_ <: AnyRef, _]
33

44
abstract trait BippyBud[A <: AnyRef, B, C <: List[A]] extends AnyRef
5-
extest.BippyBud[A,B,C] forSome { A <: AnyRef; B; C <: List[A] }
5+
extest.BippyBud[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1; type ?2 <: List[?0] }
66

77
abstract trait BippyLike[A <: AnyRef, B <: List[A], This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B]] extends AnyRef
8-
extest.BippyLike[A,B,This] forSome { A <: AnyRef; B <: List[A]; This <: extest.BippyLike[A,B,This] with extest.Bippy[A,B] }
8+
extest.BippyLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.BippyLike[?0,?1,?2] with extest.Bippy[?0,?1] }
99

1010
abstract trait Contra[-A >: AnyRef, -B] extends AnyRef
11-
extest.Contra[AnyRef, _]
11+
extest.Contra[_ >: AnyRef, _]
1212

1313
abstract trait ContraLike[-A >: AnyRef, -B >: List[A]] extends AnyRef
14-
extest.ContraLike[A,B] forSome { -A >: AnyRef; -B >: List[A] }
14+
extest.ContraLike[?0,?1] forSome { type ?0 >: AnyRef; type ?1 >: List[?0] }
1515

1616
abstract trait Cov01[+A <: AnyRef, +B] extends AnyRef
17-
extest.Cov01[AnyRef,Any]
17+
extest.Cov01[_ <: AnyRef, _]
1818

1919
abstract trait Cov02[+A <: AnyRef, B] extends AnyRef
20-
extest.Cov02[AnyRef, _]
20+
extest.Cov02[_ <: AnyRef, _]
2121

2222
abstract trait Cov03[+A <: AnyRef, -B] extends AnyRef
23-
extest.Cov03[AnyRef, _]
23+
extest.Cov03[_ <: AnyRef, _]
2424

2525
abstract trait Cov04[A <: AnyRef, +B] extends AnyRef
26-
extest.Cov04[_ <: AnyRef, Any]
26+
extest.Cov04[_ <: AnyRef, _]
2727

2828
abstract trait Cov05[A <: AnyRef, B] extends AnyRef
2929
extest.Cov05[_ <: AnyRef, _]
@@ -32,7 +32,7 @@ abstract trait Cov06[A <: AnyRef, -B] extends AnyRef
3232
extest.Cov06[_ <: AnyRef, _]
3333

3434
abstract trait Cov07[-A <: AnyRef, +B] extends AnyRef
35-
extest.Cov07[_ <: AnyRef, Any]
35+
extest.Cov07[_ <: AnyRef, _]
3636

3737
abstract trait Cov08[-A <: AnyRef, B] extends AnyRef
3838
extest.Cov08[_ <: AnyRef, _]
@@ -41,16 +41,16 @@ abstract trait Cov09[-A <: AnyRef, -B] extends AnyRef
4141
extest.Cov09[_ <: AnyRef, _]
4242

4343
abstract trait Cov11[+A <: AnyRef, +B <: List[_]] extends AnyRef
44-
extest.Cov11[AnyRef,List[_]]
44+
extest.Cov11[_ <: AnyRef, _ <: List[_]]
4545

4646
abstract trait Cov12[+A <: AnyRef, B <: List[_]] extends AnyRef
47-
extest.Cov12[AnyRef, _ <: List[_]]
47+
extest.Cov12[_ <: AnyRef, _ <: List[_]]
4848

4949
abstract trait Cov13[+A <: AnyRef, -B <: List[_]] extends AnyRef
50-
extest.Cov13[AnyRef, _ <: List[_]]
50+
extest.Cov13[_ <: AnyRef, _ <: List[_]]
5151

5252
abstract trait Cov14[A <: AnyRef, +B <: List[_]] extends AnyRef
53-
extest.Cov14[_ <: AnyRef, List[_]]
53+
extest.Cov14[_ <: AnyRef, _ <: List[_]]
5454

5555
abstract trait Cov15[A <: AnyRef, B <: List[_]] extends AnyRef
5656
extest.Cov15[_ <: AnyRef, _ <: List[_]]
@@ -59,7 +59,7 @@ abstract trait Cov16[A <: AnyRef, -B <: List[_]] extends AnyRef
5959
extest.Cov16[_ <: AnyRef, _ <: List[_]]
6060

6161
abstract trait Cov17[-A <: AnyRef, +B <: List[_]] extends AnyRef
62-
extest.Cov17[_ <: AnyRef, List[_]]
62+
extest.Cov17[_ <: AnyRef, _ <: List[_]]
6363

6464
abstract trait Cov18[-A <: AnyRef, B <: List[_]] extends AnyRef
6565
extest.Cov18[_ <: AnyRef, _ <: List[_]]
@@ -68,16 +68,16 @@ abstract trait Cov19[-A <: AnyRef, -B <: List[_]] extends AnyRef
6868
extest.Cov19[_ <: AnyRef, _ <: List[_]]
6969

7070
abstract trait Cov21[+A, +B] extends AnyRef
71-
extest.Cov21[Any,Any]
71+
extest.Cov21[_, _]
7272

7373
abstract trait Cov22[+A, B] extends AnyRef
74-
extest.Cov22[Any, _]
74+
extest.Cov22[_, _]
7575

7676
abstract trait Cov23[+A, -B] extends AnyRef
77-
extest.Cov23[Any, _]
77+
extest.Cov23[_, _]
7878

7979
abstract trait Cov24[A, +B] extends AnyRef
80-
extest.Cov24[_, Any]
80+
extest.Cov24[_, _]
8181

8282
abstract trait Cov25[A, B] extends AnyRef
8383
extest.Cov25[_, _]
@@ -86,7 +86,7 @@ abstract trait Cov26[A, -B] extends AnyRef
8686
extest.Cov26[_, _]
8787

8888
abstract trait Cov27[-A, +B] extends AnyRef
89-
extest.Cov27[_, Any]
89+
extest.Cov27[_, _]
9090

9191
abstract trait Cov28[-A, B] extends AnyRef
9292
extest.Cov28[_, _]
@@ -95,43 +95,43 @@ abstract trait Cov29[-A, -B] extends AnyRef
9595
extest.Cov29[_, _]
9696

9797
abstract trait Cov31[+A, +B, C <: (A, B)] extends AnyRef
98-
extest.Cov31[A,B,C] forSome { +A; +B; C <: (A, B) }
98+
extest.Cov31[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
9999

100100
abstract trait Cov32[+A, B, C <: (A, B)] extends AnyRef
101-
extest.Cov32[A,B,C] forSome { +A; B; C <: (A, B) }
101+
extest.Cov32[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
102102

103103
abstract trait Cov33[+A, -B, C <: Tuple2[A, _]] extends AnyRef
104-
extest.Cov33[A,B,C] forSome { +A; -B; C <: Tuple2[A, _] }
104+
extest.Cov33[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
105105

106106
abstract trait Cov34[A, +B, C <: (A, B)] extends AnyRef
107-
extest.Cov34[A,B,C] forSome { A; +B; C <: (A, B) }
107+
extest.Cov34[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
108108

109109
abstract trait Cov35[A, B, C <: (A, B)] extends AnyRef
110-
extest.Cov35[A,B,C] forSome { A; B; C <: (A, B) }
110+
extest.Cov35[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: (?0, ?1) }
111111

112112
abstract trait Cov36[A, -B, C <: Tuple2[A, _]] extends AnyRef
113-
extest.Cov36[A,B,C] forSome { A; -B; C <: Tuple2[A, _] }
113+
extest.Cov36[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[?0, _] }
114114

115115
abstract trait Cov37[-A, +B, C <: Tuple2[_, B]] extends AnyRef
116-
extest.Cov37[A,B,C] forSome { -A; +B; C <: Tuple2[_, B] }
116+
extest.Cov37[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
117117

118118
abstract trait Cov38[-A, B, C <: Tuple2[_, B]] extends AnyRef
119-
extest.Cov38[A,B,C] forSome { -A; B; C <: Tuple2[_, B] }
119+
extest.Cov38[?0,?1,?2] forSome { type ?0; type ?1; type ?2 <: Tuple2[_, ?1] }
120120

121121
abstract trait Cov39[-A, -B, C <: Tuple2[_, _]] extends AnyRef
122122
extest.Cov39[_, _, _ <: Tuple2[_, _]]
123123

124124
abstract trait Cov41[+A >: Null, +B] extends AnyRef
125-
extest.Cov41[Any,Any]
125+
extest.Cov41[_ >: Null, _]
126126

127127
abstract trait Cov42[+A >: Null, B] extends AnyRef
128-
extest.Cov42[Any, _]
128+
extest.Cov42[_ >: Null, _]
129129

130130
abstract trait Cov43[+A >: Null, -B] extends AnyRef
131-
extest.Cov43[Any, _]
131+
extest.Cov43[_ >: Null, _]
132132

133133
abstract trait Cov44[A >: Null, +B] extends AnyRef
134-
extest.Cov44[_ >: Null, Any]
134+
extest.Cov44[_ >: Null, _]
135135

136136
abstract trait Cov45[A >: Null, B] extends AnyRef
137137
extest.Cov45[_ >: Null, _]
@@ -140,7 +140,7 @@ abstract trait Cov46[A >: Null, -B] extends AnyRef
140140
extest.Cov46[_ >: Null, _]
141141

142142
abstract trait Cov47[-A >: Null, +B] extends AnyRef
143-
extest.Cov47[_ >: Null, Any]
143+
extest.Cov47[_ >: Null, _]
144144

145145
abstract trait Cov48[-A >: Null, B] extends AnyRef
146146
extest.Cov48[_ >: Null, _]
@@ -149,8 +149,8 @@ abstract trait Cov49[-A >: Null, -B] extends AnyRef
149149
extest.Cov49[_ >: Null, _]
150150

151151
abstract trait Covariant[+A <: AnyRef, +B] extends AnyRef
152-
extest.Covariant[AnyRef,Any]
152+
extest.Covariant[_ <: AnyRef, _]
153153

154154
abstract trait CovariantLike[+A <: AnyRef, +B <: List[A], +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B]] extends AnyRef
155-
extest.CovariantLike[A,B,This] forSome { +A <: AnyRef; +B <: List[A]; +This <: extest.CovariantLike[A,B,This] with extest.Covariant[A,B] }
155+
extest.CovariantLike[?0,?1,?2] forSome { type ?0 <: AnyRef; type ?1 <: List[?0]; type ?2 <: extest.CovariantLike[?0,?1,?2] with extest.Covariant[?0,?1] }
156156

test/files/run/existentials-in-compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ package extest {
7979
exitingTyper {
8080
clazz.info
8181
println(clazz.defString)
82-
println(" " + classExistentialType(clazz) + "\n")
82+
println(" " + classExistentialType(clazz.owner.typeOfThis, clazz) + "\n")
8383
}
8484
}
8585
}

0 commit comments

Comments
 (0)