Skip to content

Commit a2b0091

Browse files
committed
Fix false unreachable due to opaqueness
1 parent ec2b8bc commit a2b0091

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ object Types extends TypeUtils {
197197
*/
198198
def isRef(sym: Symbol, skipRefined: Boolean = true)(using Context): Boolean = this match {
199199
case this1: TypeRef =>
200-
this1.info match { // see comment in Namer#typeDefSig
200+
this1.info match { // see comment in Namer#TypeDefCompleter#typeSig
201201
case TypeAlias(tp) => tp.isRef(sym, skipRefined)
202202
case _ => this1.symbol eq sym
203203
}

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -668,17 +668,15 @@ object SpaceEngine {
668668
}
669669

670670
extension (tp: Type)
671-
/** A type is decomposable to children if it has a simple kind, it's sealed,
672-
* abstract (or a trait) - so its not a sealed concrete class that can be instantiated on its own,
673-
* has no anonymous children, which we wouldn't be able to name as counter-examples,
674-
* but does have children.
675-
*
676-
* A sealed trait with no subclasses is considered not decomposable and thus is treated as an opaque type.
677-
* A sealed trait with subclasses that then get removed after `refineUsingParent`, decomposes to the empty list.
678-
* So that's why we consider whether a type has children. */
679671
def isDecomposableToChildren(using Context): Boolean =
680-
val cls = tp.classSymbol
681-
tp.hasSimpleKind && cls.is(Sealed) && cls.isOneOf(AbstractOrTrait) && !cls.hasAnonymousChild && cls.children.nonEmpty
672+
val sym = tp.typeSymbol // e.g. Foo[List[Int]] = type Foo (i19275)
673+
val cls = tp.classSymbol // e.g. Foo[List[Int]] = class List
674+
tp.hasSimpleKind // can't decompose higher-kinded types
675+
&& cls.is(Sealed)
676+
&& cls.isOneOf(AbstractOrTrait) // ignore sealed non-abstract classes
677+
&& !cls.hasAnonymousChild // can't name anonymous classes as counter-examples
678+
&& cls.children.nonEmpty // can't decompose without children
679+
&& !sym.isOpaqueAlias // can't instantiate subclasses to conform to an opaque type (i19275)
682680

683681
val ListOfNoType = List(NoType)
684682
val ListOfTypNoType = ListOfNoType.map(Typ(_, decomposed = true))

tests/warn/i19275.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
opaque type Foo[A] <: A = A
2+
3+
class Test:
4+
def t1(x: Option[Foo[List[Int]]]): Unit = x match
5+
case Some(foo) =>
6+
case None =>

0 commit comments

Comments
 (0)