Skip to content

Commit 21e5721

Browse files
committed
handle binder type symbols in extractor patterns
1 parent 7655503 commit 21e5721

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import core._
66
import Types._
77
import Contexts._
88
import Flags._
9-
import ast.Trees._
10-
import ast.tpd
9+
import ast._
10+
import Trees._
1111
import Decorators._
1212
import Symbols._
1313
import StdNames._
@@ -299,16 +299,15 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
299299
if (res) Typ(and, true) else Empty
300300
}
301301

302-
/* Whether the extractor is irrefutable */
302+
/** Whether the extractor is irrefutable */
303303
def irrefutable(unapp: Tree): Boolean = {
304304
// TODO: optionless patmat
305305
unapp.tpe.widen.finalResultType.isRef(scalaSomeClass) ||
306306
(unapp.symbol.is(Synthetic) && unapp.symbol.owner.linkedClass.is(Case)) ||
307307
productArity(unapp.tpe.widen.finalResultType) > 0
308308
}
309309

310-
/** Return the space that represents the pattern `pat`
311-
*/
310+
/** Return the space that represents the pattern `pat` */
312311
def project(pat: Tree): Space = pat match {
313312
case Literal(c) =>
314313
if (c.value.isInstanceOf[Symbol])
@@ -326,9 +325,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
326325
if (fun.symbol.owner == scalaSeqFactoryClass)
327326
projectSeq(pats)
328327
else
329-
Prod(pat.tpe.stripAnnots, fun.tpe, fun.symbol, projectSeq(pats) :: Nil, irrefutable(fun))
328+
Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, projectSeq(pats) :: Nil, irrefutable(fun))
330329
else
331-
Prod(pat.tpe.stripAnnots, fun.tpe, fun.symbol, pats.map(project), irrefutable(fun))
330+
Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.map(project), irrefutable(fun))
332331
case Typed(pat @ UnApply(_, _, _), _) => project(pat)
333332
case Typed(expr, tpt) =>
334333
Typ(erase(expr.tpe.stripAnnots), true)

tests/patmat/enum-approx.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
24: Pattern Match Exhaustivity: Fun.ConstNullClass(_)

tests/patmat/enum-approx.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
enum Fun[-T, +U >: Null] {
2+
def f: T => U = this match {
3+
case Identity(g) => g
4+
case ConstNull => (_ => null)
5+
case ConstNullClass(y) => (_ => null)
6+
case ConstNullSimple => null
7+
}
8+
9+
case Identity[T, U >: Null](g: T => U) extends Fun[T, U]
10+
case ConstNull
11+
case ConstNullClass(x: T)
12+
case ConstNullSimple
13+
}
14+
15+
object Test {
16+
def main(args: Array[String]) = {
17+
val x: Null = Fun.ConstNull.f("abc")
18+
val y: Null = Fun.ConstNullClass("hello").f("abc")
19+
assert(Fun.ConstNullSimple.f == null)
20+
}
21+
22+
import Fun._
23+
24+
def f[T, U >: Null](f: Fun[T, U]): T => U = f match {
25+
case Identity(g) => g
26+
case ConstNull => (_ => null)
27+
case ConstNullClass(y: Int) => (_ => null)
28+
case ConstNullSimple => null
29+
}
30+
}
31+

0 commit comments

Comments
 (0)