Skip to content

Commit 28e9bb7

Browse files
committed
Avoid forming And/Or types with equal operands.
This can happen in particular in derivedAnd/Or type, when applying a substitution or other mapping which identifies two types that were different before.
1 parent e1d53f0 commit 28e9bb7

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ class TypeComparer(initctx: Context) extends DotClass {
371371
val sd = tp1.denot.asSingleDenotation
372372
def derivedRef(tp: Type) =
373373
NamedType(tp1.prefix, tp1.name, sd.derivedSingleDenotation(sd.symbol, tp))
374-
secondTry(OrType(derivedRef(tp11), derivedRef(tp12)), tp2)
374+
secondTry(OrType.make(derivedRef(tp11), derivedRef(tp12)), tp2)
375375
case TypeBounds(lo1, hi1) =>
376376
if ((tp1.symbol is GADTFlexType) && !isSubTypeWhenFrozen(hi1, tp2))
377377
trySetType(tp1, TypeBounds(lo1, hi1 & tp2))

src/dotty/tools/dotc/core/Types.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,19 +1353,18 @@ object Types {
13531353
def tp1: Type
13541354
def tp2: Type
13551355
def isAnd: Boolean
1356-
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): AndOrType // needed?
1357-
1356+
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): Type // needed?
13581357
}
13591358

13601359
abstract case class AndType(tp1: Type, tp2: Type) extends CachedGroundType with AndOrType {
13611360

13621361
def isAnd = true
13631362

1364-
def derivedAndType(tp1: Type, tp2: Type)(implicit ctx: Context): AndType =
1363+
def derivedAndType(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
13651364
if ((tp1 eq this.tp1) && (tp2 eq this.tp2)) this
1366-
else AndType(tp1, tp2)
1365+
else AndType.make(tp1, tp2)
13671366

1368-
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): AndOrType =
1367+
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
13691368
derivedAndType(tp1, tp2)
13701369

13711370
override def computeHash = doHash(tp1, tp2)
@@ -1381,18 +1380,19 @@ object Types {
13811380
def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context) = {
13821381
unique(new CachedAndType(tp1, tp2))
13831382
}
1383+
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
1384+
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
13841385
}
13851386

13861387
abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType with AndOrType {
13871388
assert(tp1.isInstanceOf[ValueType] && tp2.isInstanceOf[ValueType])
1388-
13891389
def isAnd = false
13901390

1391-
def derivedOrType(tp1: Type, tp2: Type)(implicit ctx: Context): OrType =
1391+
def derivedOrType(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
13921392
if ((tp1 eq this.tp1) && (tp2 eq this.tp2)) this
1393-
else OrType(tp1, tp2)
1393+
else OrType.make(tp1, tp2)
13941394

1395-
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): AndOrType =
1395+
def derivedAndOrType(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
13961396
derivedOrType(tp1, tp2)
13971397

13981398
override def computeHash = doHash(tp1, tp2)
@@ -1403,6 +1403,8 @@ object Types {
14031403
object OrType {
14041404
def apply(tp1: Type, tp2: Type)(implicit ctx: Context) =
14051405
unique(new CachedOrType(tp1, tp2))
1406+
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
1407+
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
14061408
}
14071409

14081410
// ----- Method types: MethodType/ExprType/PolyType -------------------------------

0 commit comments

Comments
 (0)