@@ -1354,6 +1354,11 @@ object Types {
1354
1354
* compute hash and use it as the type's hashCode.
1355
1355
*/
1356
1356
def hash : Int
1357
+
1358
+ /** Equality used for hash-consing; uses `eq` on all recursive invocations.
1359
+ */
1360
+ def eql (that : Type ): Boolean = this .equals(that)
1361
+
1357
1362
} // end Type
1358
1363
1359
1364
// ----- Type categories ----------------------------------------------
@@ -1927,6 +1932,8 @@ object Types {
1927
1932
1928
1933
override def computeHash = unsupported(" computeHash" )
1929
1934
1935
+ override def eql (that : Type ) = this eq that // safe because named types are hash-consed separately
1936
+
1930
1937
/* A version of toString which also prints aliases. Can be used for debugging
1931
1938
override def toString =
1932
1939
if (isTerm) s"TermRef($prefix, $name)"
@@ -2097,7 +2104,13 @@ object Types {
2097
2104
def cls (implicit ctx : Context ): ClassSymbol = tref.stableInRunSymbol.asClass
2098
2105
override def underlying (implicit ctx : Context ): Type =
2099
2106
if (ctx.erasedTypes) tref else cls.classInfo.selfType
2107
+
2100
2108
override def computeHash = doHash(tref)
2109
+
2110
+ override def eql (that : Type ) = that match {
2111
+ case that : ThisType => tref.eq(that.tref)
2112
+ case _ => false
2113
+ }
2101
2114
}
2102
2115
2103
2116
final class CachedThisType (tref : TypeRef ) extends ThisType (tref)
@@ -2119,7 +2132,13 @@ object Types {
2119
2132
def derivedSuperType (thistpe : Type , supertpe : Type )(implicit ctx : Context ) =
2120
2133
if ((thistpe eq this .thistpe) && (supertpe eq this .supertpe)) this
2121
2134
else SuperType (thistpe, supertpe)
2135
+
2122
2136
override def computeHash = doHash(thistpe, supertpe)
2137
+
2138
+ override def eql (that : Type ) = that match {
2139
+ case that : SuperType => thistpe.eq(that.thistpe) && supertpe.eq(that.supertpe)
2140
+ case _ => false
2141
+ }
2123
2142
}
2124
2143
2125
2144
final class CachedSuperType (thistpe : Type , supertpe : Type ) extends SuperType (thistpe, supertpe)
@@ -2134,6 +2153,7 @@ object Types {
2134
2153
/** A constant type with single `value`. */
2135
2154
abstract case class ConstantType (value : Constant ) extends CachedProxyType with SingletonType {
2136
2155
override def underlying (implicit ctx : Context ) = value.tpe
2156
+
2137
2157
override def computeHash = doHash(value)
2138
2158
}
2139
2159
@@ -2161,7 +2181,7 @@ object Types {
2161
2181
def evaluating = computed && myRef == null
2162
2182
override def underlying (implicit ctx : Context ) = ref
2163
2183
override def toString = s " LazyRef( ${if (computed) myRef else " ..." }) "
2164
- override def equals (other : Any ) = this eq other.asInstanceOf [AnyRef ]
2184
+ override def equals (other : Any ) = this .eq( other.asInstanceOf [AnyRef ])
2165
2185
override def hashCode = System .identityHashCode(this )
2166
2186
}
2167
2187
@@ -2199,6 +2219,14 @@ object Types {
2199
2219
else parent
2200
2220
2201
2221
override def computeHash = doHash(refinedName, refinedInfo, parent)
2222
+
2223
+ override def eql (that : Type ) = that match {
2224
+ case that : RefinedType =>
2225
+ refinedName.eq(that.refinedName) &&
2226
+ refinedInfo.eq(that.refinedInfo) &&
2227
+ parent.eq(that.parent)
2228
+ case _ => false
2229
+ }
2202
2230
}
2203
2231
2204
2232
class CachedRefinedType (parent : Type , refinedName : Name , refinedInfo : Type )
@@ -2240,11 +2268,6 @@ object Types {
2240
2268
if (parent eq this .parent) this
2241
2269
else RecType .closeOver(rt => parent.substRecThis(this , rt.recThis))
2242
2270
2243
- override def equals (other : Any ) = other match {
2244
- case other : RecType => other.parent == this .parent
2245
- case _ => false
2246
- }
2247
-
2248
2271
def isReferredToBy (tp : Type )(implicit ctx : Context ): Boolean = {
2249
2272
val refacc = new TypeAccumulator [Boolean ] {
2250
2273
override def apply (x : Boolean , tp : Type ) = x || {
@@ -2260,6 +2283,17 @@ object Types {
2260
2283
}
2261
2284
2262
2285
override def computeHash = doHash(parent)
2286
+
2287
+ override def equals (that : Any ) = that match {
2288
+ case that : RecType => parent == that.parent
2289
+ case _ => false
2290
+ }
2291
+
2292
+ override def eql (that : Type ) = that match {
2293
+ case that : RecType => parent.eq(that.parent)
2294
+ case _ => false
2295
+ }
2296
+
2263
2297
override def toString = s " RecType( $parent | $hashCode) "
2264
2298
2265
2299
private def checkInst (implicit ctx : Context ): this .type = this // debug hook
@@ -2355,6 +2389,11 @@ object Types {
2355
2389
derivedAndType(tp1, tp2)
2356
2390
2357
2391
override def computeHash = doHash(tp1, tp2)
2392
+
2393
+ override def eql (that : Type ) = that match {
2394
+ case that : AndType => tp1.eq(that.tp1) && tp2.eq(that.tp2)
2395
+ case _ => false
2396
+ }
2358
2397
}
2359
2398
2360
2399
final class CachedAndType (tp1 : Type , tp2 : Type ) extends AndType (tp1, tp2)
@@ -2411,6 +2450,11 @@ object Types {
2411
2450
derivedOrType(tp1, tp2)
2412
2451
2413
2452
override def computeHash = doHash(tp1, tp2)
2453
+
2454
+ override def eql (that : Type ) = that match {
2455
+ case that : OrType => tp1.eq(that.tp1) && tp2.eq(that.tp2)
2456
+ case _ => false
2457
+ }
2414
2458
}
2415
2459
2416
2460
final class CachedOrType (tp1 : Type , tp2 : Type ) extends OrType (tp1, tp2)
@@ -2465,10 +2509,18 @@ object Types {
2465
2509
extends CachedProxyType with TermType with MethodicType {
2466
2510
override def resultType (implicit ctx : Context ): Type = resType
2467
2511
override def underlying (implicit ctx : Context ): Type = resType
2512
+
2468
2513
def computeSignature (implicit ctx : Context ): Signature = resultSignature
2514
+
2469
2515
def derivedExprType (resType : Type )(implicit ctx : Context ) =
2470
2516
if (resType eq this .resType) this else ExprType (resType)
2517
+
2471
2518
override def computeHash = doHash(resType)
2519
+
2520
+ override def eql (that : Type ) = that match {
2521
+ case that : ExprType => resType.eq(that.resType)
2522
+ case _ => false
2523
+ }
2472
2524
}
2473
2525
2474
2526
final class CachedExprType (resultType : Type ) extends ExprType (resultType)
@@ -2555,10 +2607,20 @@ object Types {
2555
2607
// Defined here instead of in LambdaType for efficiency
2556
2608
final override def equals (that : Any ) = that match {
2557
2609
case that : HKLambda =>
2558
- this .paramNames == that.paramNames &&
2559
- this .paramInfos == that.paramInfos &&
2560
- this .resType == that.resType &&
2561
- (this .companion eq that.companion)
2610
+ paramNames == that.paramNames &&
2611
+ paramInfos == that.paramInfos &&
2612
+ resType == that.resType &&
2613
+ companion.eq(that.companion)
2614
+ case _ =>
2615
+ false
2616
+ }
2617
+
2618
+ final override def eql (that : Type ) = that match {
2619
+ case that : HKLambda =>
2620
+ paramNames.equals(that.paramNames) &&
2621
+ paramInfos.equals(that.paramInfos) &&
2622
+ resType.equals(that.resType) &&
2623
+ companion.eq(that.companion)
2562
2624
case _ =>
2563
2625
false
2564
2626
}
@@ -2570,10 +2632,20 @@ object Types {
2570
2632
// Defined here instead of in LambdaType for efficiency
2571
2633
final override def equals (that : Any ) = that match {
2572
2634
case that : MethodOrPoly =>
2573
- this .paramNames == that.paramNames &&
2574
- this .paramInfos == that.paramInfos &&
2575
- this .resType == that.resType &&
2576
- (this .companion eq that.companion)
2635
+ paramNames == that.paramNames &&
2636
+ paramInfos == that.paramInfos &&
2637
+ resType == that.resType &&
2638
+ companion.eq(that.companion)
2639
+ case _ =>
2640
+ false
2641
+ }
2642
+
2643
+ final override def eql (that : Type ) = that match {
2644
+ case that : MethodOrPoly =>
2645
+ paramNames.eqElements(that.paramNames) &&
2646
+ paramInfos.eqElements(that.paramInfos) &&
2647
+ resType.eq(that.resType) &&
2648
+ companion.eq(that.companion)
2577
2649
case _ =>
2578
2650
false
2579
2651
}
@@ -3046,6 +3118,7 @@ object Types {
3046
3118
final class CachedAppliedType (tycon : Type , args : List [Type ], hc : Int ) extends AppliedType (tycon, args) {
3047
3119
myHash = hc
3048
3120
override def computeHash = unsupported(" computeHash" )
3121
+ override def eql (that : Type ) = this eq that // safe because applied types are hash-consed separately
3049
3122
}
3050
3123
3051
3124
object AppliedType {
@@ -3093,6 +3166,11 @@ object Types {
3093
3166
def derivedTypeArgRef (prefix : Type )(implicit ctx : Context ): Type =
3094
3167
if (prefix eq this .prefix) this else TypeArgRef (prefix, clsRef, idx)
3095
3168
override def computeHash = doHash(idx, prefix, clsRef)
3169
+
3170
+ override def eql (that : Type ) = that match {
3171
+ case that : TypeArgRef => prefix.eq(that.prefix) && clsRef.eq(that.clsRef) && idx == that.idx
3172
+ case _ => false
3173
+ }
3096
3174
}
3097
3175
3098
3176
final class CachedTypeArgRef (prefix : Type , clsRef : TypeRef , idx : Int ) extends TypeArgRef (prefix, clsRef, idx)
@@ -3134,11 +3212,10 @@ object Types {
3134
3212
}
3135
3213
3136
3214
override def computeHash = doHash(paramNum, binder.identityHash)
3215
+
3137
3216
override def equals (that : Any ) = that match {
3138
- case that : ParamRef =>
3139
- (this .binder eq that.binder) && this .paramNum == that.paramNum
3140
- case _ =>
3141
- false
3217
+ case that : ParamRef => binder.eq(that.binder) && paramNum == that.paramNum
3218
+ case _ => false
3142
3219
}
3143
3220
3144
3221
override def toString =
@@ -3188,10 +3265,12 @@ object Types {
3188
3265
// need to customize hashCode and equals to prevent infinite recursion
3189
3266
// between RecTypes and RecRefs.
3190
3267
override def computeHash = addDelta(binder.identityHash, 41 )
3268
+
3191
3269
override def equals (that : Any ) = that match {
3192
- case that : RecThis => this . binder eq that.binder
3270
+ case that : RecThis => binder.eq( that.binder)
3193
3271
case _ => false
3194
3272
}
3273
+
3195
3274
override def toString =
3196
3275
try s " RecThis( ${binder.hashCode}) "
3197
3276
catch {
@@ -3207,7 +3286,7 @@ object Types {
3207
3286
def derivedSkolemType (info : Type )(implicit ctx : Context ) =
3208
3287
if (info eq this .info) this else SkolemType (info)
3209
3288
override def hashCode : Int = identityHash
3210
- override def equals (that : Any ) = this eq that.asInstanceOf [AnyRef ]
3289
+ override def equals (that : Any ) = this .eq( that.asInstanceOf [AnyRef ])
3211
3290
3212
3291
def withName (name : Name ): this .type = { myRepr = name; this }
3213
3292
@@ -3309,7 +3388,7 @@ object Types {
3309
3388
}
3310
3389
3311
3390
override def computeHash : Int = identityHash
3312
- override def equals (that : Any ) = this eq that.asInstanceOf [AnyRef ]
3391
+ override def equals (that : Any ) = this .eq( that.asInstanceOf [AnyRef ])
3313
3392
3314
3393
override def toString = {
3315
3394
def instStr = if (inst.exists) s " -> $inst" else " "
@@ -3389,6 +3468,16 @@ object Types {
3389
3468
3390
3469
override def computeHash = doHash(cls, prefix)
3391
3470
3471
+ override def eql (that : Type ) = that match {
3472
+ case that : ClassInfo =>
3473
+ prefix.eq(that.prefix) &&
3474
+ cls.eq(that.cls) &&
3475
+ classParents.eqElements(that.classParents) &&
3476
+ decls.eq(that.decls) &&
3477
+ selfInfo.eq(that.selfInfo)
3478
+ case _ => false
3479
+ }
3480
+
3392
3481
override def toString = s " ClassInfo( $prefix, $cls, $classParents) "
3393
3482
}
3394
3483
@@ -3459,15 +3548,16 @@ object Types {
3459
3548
3460
3549
override def computeHash = doHash(lo, hi)
3461
3550
3462
- // @!!! we are not systematic when we do referntial vs structural comparisons.
3463
- // Do referential everywhere?
3464
3551
override def equals (that : Any ): Boolean = that match {
3465
- case that : TypeAlias =>
3466
- false
3467
- case that : TypeBounds =>
3468
- (this .lo eq that.lo) && (this .hi eq that.hi)
3469
- case _ =>
3470
- false
3552
+ case that : TypeAlias => false
3553
+ case that : TypeBounds => lo == that.lo && hi == that.hi
3554
+ case _ => false
3555
+ }
3556
+
3557
+ override def eql (that : Type ) = that match {
3558
+ case that : TypeAlias => false
3559
+ case that : TypeBounds => lo.eq(that.lo) && hi.eq(that.hi)
3560
+ case _ => false
3471
3561
}
3472
3562
}
3473
3563
@@ -3482,10 +3572,13 @@ object Types {
3482
3572
override def computeHash = doHash(alias)
3483
3573
3484
3574
override def equals (that : Any ): Boolean = that match {
3485
- case that : TypeAlias =>
3486
- this .alias eq that.alias
3487
- case _ =>
3488
- false
3575
+ case that : TypeAlias => alias == that.alias
3576
+ case _ => false
3577
+ }
3578
+
3579
+ override def eql (that : Type ): Boolean = that match {
3580
+ case that : TypeAlias => alias.eq(that.alias)
3581
+ case _ => false
3489
3582
}
3490
3583
}
3491
3584
@@ -3530,9 +3623,15 @@ object Types {
3530
3623
3531
3624
/** The type of an erased array */
3532
3625
abstract case class JavaArrayType (elemType : Type ) extends CachedGroundType with ValueType {
3533
- override def computeHash = doHash(elemType)
3534
3626
def derivedJavaArrayType (elemtp : Type )(implicit ctx : Context ) =
3535
3627
if (elemtp eq this .elemType) this else JavaArrayType (elemtp)
3628
+
3629
+ override def computeHash = doHash(elemType)
3630
+
3631
+ override def eql (that : Type ) = that match {
3632
+ case that : JavaArrayType => elemType.eq(that.elemType)
3633
+ case _ => false
3634
+ }
3536
3635
}
3537
3636
final class CachedJavaArrayType (elemType : Type ) extends JavaArrayType (elemType)
3538
3637
object JavaArrayType {
@@ -3586,7 +3685,13 @@ object Types {
3586
3685
if (optBounds eq this .optBounds) this
3587
3686
else if (! optBounds.exists) WildcardType
3588
3687
else WildcardType (optBounds.asInstanceOf [TypeBounds ])
3688
+
3589
3689
override def computeHash = doHash(optBounds)
3690
+
3691
+ override def eql (that : Type ) = that match {
3692
+ case that : WildcardType => optBounds.eq(that.optBounds)
3693
+ case _ => false
3694
+ }
3590
3695
}
3591
3696
3592
3697
final class CachedWildcardType (optBounds : Type ) extends WildcardType (optBounds)
0 commit comments