Skip to content

Commit d04005c

Browse files
committed
Fix isEffectivelySingleton
As usual, OrTypes need to be excluded. a.type | b.type is not effectively a singleton. It seems to be an easy trap to fall into. Follow-up to #20474
1 parent 9b5ab2e commit d04005c

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,12 @@ object Types extends TypeUtils {
329329
def isSingleton(using Context): Boolean = dealias.isInstanceOf[SingletonType]
330330

331331
/** Is this type a (possibly aliased) singleton type or a type proxy
332-
* or Or/And type known to be a singleton type?
332+
* or an AndType where one operand is effectively a singleton?
333333
*/
334334
def isEffectivelySingleton(using Context): Boolean = dealias match
335335
case tp: SingletonType => true
336336
case tp: TypeProxy => tp.superType.isEffectivelySingleton
337337
case AndType(tpL, tpR) => tpL.isEffectivelySingleton || tpR.isEffectivelySingleton
338-
case OrType(tpL, tpR) => tpL.isEffectivelySingleton && tpR.isEffectivelySingleton
339338
case _ => false
340339

341340
/** Is this upper-bounded by a (possibly aliased) singleton type?

tests/neg/i20474.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class A
2+
class B extends A
3+
4+
def f(a: A, c: A) =
5+
val b1: a.type = a
6+
val b2: a.type & B = a.asInstanceOf[a.type & B]
7+
val b3: c.type & A = c
8+
val b4: a.type | c.type = c
9+
10+
val d1: b1.type = a
11+
val d2: b2.type = a // ok
12+
val d3: b3.type = a // error
13+
val d4: b4.type = a // error

0 commit comments

Comments
 (0)