Skip to content

Commit 7cc8e3c

Browse files
committed
Warn when matching against an opaque type
This is really analogous to matching against an abstract type, and should be handled the same way.
1 parent e834186 commit 7cc8e3c

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ object TypeTestsCasts {
5353
* 7. if `P` is a refinement type, FALSE
5454
* 8. otherwise, TRUE
5555
*/
56-
def checkable(X: Type, P: Type, span: Span)(using Context): Boolean = {
56+
def checkable(X: Type, P: Type, span: Span)(using Context): Boolean = atPhase(Phases.refchecksPhase.next) {
57+
// Run just before ElimOpaque transform (which follows RefChecks)
5758
def isAbstract(P: Type) = !P.dealias.typeSymbol.isClass
5859

5960
def replaceP(tp: Type)(using Context) = new TypeMap {
@@ -71,7 +72,7 @@ object TypeTestsCasts {
7172
case tref: TypeRef if tref.typeSymbol.isPatternBound =>
7273
if (variance == 1) tref.info.hiBound
7374
else if (variance == -1) tref.info.loBound
74-
else OrType(defn.AnyType, defn.NothingType, soft = true)
75+
else OrType(defn.AnyType, defn.NothingType, soft = true) // TODO: what does this line do?
7576
case _ => mapOver(tp)
7677
}
7778
}.apply(tp)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
case class C()
2+
3+
object O:
4+
opaque type T <: C = C
5+
val x: T = C()
6+
7+
def Test[T] =
8+
O.x match
9+
case _: C => ??? // ok
10+
C() match
11+
case _: O.T => ??? // error
12+
C() match
13+
case _: T => ??? // error
14+
15+
(??? : Any) match
16+
case _: List[O.T] => ??? // error
17+
(??? : Any) match
18+
case _: List[T] => ??? // error
19+
20+
21+
22+

0 commit comments

Comments
 (0)