Skip to content

Commit e17e15a

Browse files
Drop singletonInterval from lubArgs and glbArgs in TypeComparer
1 parent 73214ff commit e17e15a

File tree

3 files changed

+21
-33
lines changed

3 files changed

+21
-33
lines changed

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

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,26 +2458,6 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24582458
isSubRef(tp1, tp2) && isSubRef(tp2, tp1)
24592459
}
24602460

2461-
/** If the range `tp1..tp2` consist of a single type, that type, otherwise NoType`.
2462-
* This is the case if `tp1 =:= tp2`, but also if `tp1 <:< tp2`, `tp1` is a singleton type,
2463-
* and `tp2` derives from `scala.Singleton` (or vice-versa). Examples of the latter case:
2464-
*
2465-
* "name".type .. Singleton
2466-
* "name".type .. String & Singleton
2467-
* Singleton .. "name".type
2468-
* String & Singleton .. "name".type
2469-
*
2470-
* All consist of the single type `"name".type`.
2471-
*/
2472-
def singletonInterval(tp1: Type, tp2: Type): Type = {
2473-
def isSingletonBounds(lo: Type, hi: Type) =
2474-
lo.isSingleton && hi.derivesFrom(defn.SingletonClass) && isSubTypeWhenFrozen(lo, hi)
2475-
if (isSameTypeWhenFrozen(tp1, tp2)) tp1
2476-
else if (isSingletonBounds(tp1, tp2)) tp1
2477-
else if (isSingletonBounds(tp2, tp1)) tp2
2478-
else NoType
2479-
}
2480-
24812461
/** The greatest lower bound of two types */
24822462
def glb(tp1: Type, tp2: Type): Type = // trace(s"glb(${tp1.show}, ${tp2.show})", subtyping, show = true):
24832463
if tp1 eq tp2 then tp1
@@ -2583,7 +2563,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25832563
case tparam :: tparamsRest =>
25842564
val arg1 :: args1Rest = args1: @unchecked
25852565
val arg2 :: args2Rest = args2: @unchecked
2586-
val common = singletonInterval(arg1, arg2)
2566+
val common = if isSameTypeWhenFrozen(arg1, arg2) then arg1 else NoType
25872567
val v = tparam.paramVarianceSign
25882568
val lubArg =
25892569
if (common.exists) common
@@ -2615,7 +2595,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
26152595
case tparam :: tparamsRest =>
26162596
val arg1 :: args1Rest = args1: @unchecked
26172597
val arg2 :: args2Rest = args2: @unchecked
2618-
val common = singletonInterval(arg1, arg2)
2598+
val common = if isSameTypeWhenFrozen(arg1, arg2) then arg1 else NoType
26192599
val v = tparam.paramVarianceSign
26202600
val glbArg =
26212601
if (common.exists) common

tests/neg/i23435-min.scala

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11

22
type Or[+A, +B] = A | B
33

4-
object Test1:
5-
val x: Or[Int, String] & Or[String, Int] = 3
6-
val y: Or[Int & String, String & Int] = x // error
7-
val z: String = y
8-
9-
// shows the distributeAnd logic should not be applied even when
10-
// the targs are pairwise TypeComparer#singletonInterval
11-
object Test2:
12-
val x: Or["3", Singleton] & Or[Singleton, "3"] = 3
13-
val y: Or["3", "3"] = x // error
14-
val z: String = y
4+
val x: Or[Int, String] & Or[String, Int] = 3
5+
val y: Or[Int & String, String & Int] = x // error
6+
val z: String = y

tests/neg/singletonInterval.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
/** Why the singletonInterval logic cannot be applied for lubArgs and glbArgs in TypeComparer. */
3+
4+
type Or[+A, +B] = A | B
5+
6+
object TestGlb:
7+
val x: Or["3", Singleton] & Or[Singleton, "3"] = 3
8+
val y: Or["3", "3"] = x // error
9+
val z: String = y
10+
11+
object TestLub:
12+
def f[P[_, _]](x1: P["3", Singleton], x2: P[Singleton, "3"]): P["3", "3"] =
13+
val x = if true then x1 else x2
14+
x // error, was accepted because inferred type of x was `P["3", "3"]`
15+
// by going through Types.join, TypeOps.mergeRefinedOrApplied, TypeComparer#lubArgs, TypeComparer#singletonInterval
16+
val z: String = f[Or](3, 3)

0 commit comments

Comments
 (0)