Skip to content

Commit 98ecc10

Browse files
authored
Merge pull request #12288 from dotty-staging/fix-12286
Change order of operations in `lub`
2 parents e3dd0c5 + 94ecc05 commit 98ecc10

File tree

2 files changed

+38
-28
lines changed

2 files changed

+38
-28
lines changed

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

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,43 +1969,40 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
19691969
else if (!tp2.exists) tp1
19701970
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
19711971
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1
1972-
else tp2 match { // normalize to disjunctive normal form if possible.
1972+
else tp2 match
19731973
case tp2: LazyRef =>
19741974
glb(tp1, tp2.ref)
1975-
case OrType(tp21, tp22) =>
1976-
tp1 & tp21 | tp1 & tp22
19771975
case _ =>
1978-
tp1 match {
1976+
tp1 match
19791977
case tp1: LazyRef =>
19801978
glb(tp1.ref, tp2)
1981-
case OrType(tp11, tp12) =>
1982-
tp11 & tp2 | tp12 & tp2
19831979
case _ =>
19841980
val tp1a = dropIfSuper(tp1, tp2)
1985-
if (tp1a ne tp1) glb(tp1a, tp2)
1986-
else {
1981+
if tp1a ne tp1 then glb(tp1a, tp2)
1982+
else
19871983
val tp2a = dropIfSuper(tp2, tp1)
1988-
if (tp2a ne tp2) glb(tp1, tp2a)
1989-
else tp1 match {
1990-
case tp1: ConstantType =>
1991-
tp2 match {
1992-
case tp2: ConstantType =>
1993-
// Make use of the fact that the intersection of two constant types
1994-
// types which are not subtypes of each other is known to be empty.
1995-
// Note: The same does not apply to singleton types in general.
1996-
// E.g. we could have a pattern match against `x.type & y.type`
1997-
// which might succeed if `x` and `y` happen to be the same ref
1998-
// at run time. It would not work to replace that with `Nothing`.
1999-
// However, maybe we can still apply the replacement to
2000-
// types which are not explicitly written.
2001-
NothingType
1984+
if tp2a ne tp2 then glb(tp1, tp2a)
1985+
else tp2 match // normalize to disjunctive normal form if possible.
1986+
case OrType(tp21, tp22) =>
1987+
tp1 & tp21 | tp1 & tp22
1988+
case _ =>
1989+
tp1 match
1990+
case OrType(tp11, tp12) =>
1991+
tp11 & tp2 | tp12 & tp2
1992+
case tp1: ConstantType =>
1993+
tp2 match
1994+
case tp2: ConstantType =>
1995+
// Make use of the fact that the intersection of two constant types
1996+
// types which are not subtypes of each other is known to be empty.
1997+
// Note: The same does not apply to singleton types in general.
1998+
// E.g. we could have a pattern match against `x.type & y.type`
1999+
// which might succeed if `x` and `y` happen to be the same ref
2000+
// at run time. It would not work to replace that with `Nothing`.
2001+
// However, maybe we can still apply the replacement to
2002+
// types which are not explicitly written.
2003+
NothingType
2004+
case _ => andType(tp1, tp2)
20022005
case _ => andType(tp1, tp2)
2003-
}
2004-
case _ => andType(tp1, tp2)
2005-
}
2006-
}
2007-
}
2008-
}
20092006
}
20102007

20112008
def widenInUnions(using Context): Boolean =

tests/pos/i12286.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sealed trait Base { def str: String }
2+
case class One(str: String) extends Base
3+
case class Two(str: String) extends Base
4+
case class Three(str: String) extends Base
5+
6+
case class Item(_id: String)
7+
8+
private def doWithItem[T <: (One | Two | Three)]
9+
(item: Item, value: T, action: (T) => Item) = doWithItemId(item._id, value, action)
10+
private def doWithItemId[U <: (One | Two | Three)]
11+
(itemId: String, value: U, action: (U) => Item) =
12+
println(value.str)
13+
Item("_id")

0 commit comments

Comments
 (0)