diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index c47022be10af..da4f0feb2f8a 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -6,8 +6,8 @@ import core._ import Types._ import Contexts._ import Flags._ -import ast.Trees._ -import ast.tpd +import ast._ +import Trees._ import Decorators._ import Symbols._ import StdNames._ @@ -299,7 +299,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { if (res) Typ(and, true) else Empty } - /* Whether the extractor is irrefutable */ + /** Whether the extractor is irrefutable */ def irrefutable(unapp: Tree): Boolean = { // TODO: optionless patmat unapp.tpe.widen.finalResultType.isRef(scalaSomeClass) || @@ -307,8 +307,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { productArity(unapp.tpe.widen.finalResultType) > 0 } - /** Return the space that represents the pattern `pat` - */ + /** Return the space that represents the pattern `pat` */ def project(pat: Tree): Space = pat match { case Literal(c) => if (c.value.isInstanceOf[Symbol]) @@ -326,9 +325,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic { if (fun.symbol.owner == scalaSeqFactoryClass) projectSeq(pats) else - Prod(pat.tpe.stripAnnots, fun.tpe, fun.symbol, projectSeq(pats) :: Nil, irrefutable(fun)) + Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, projectSeq(pats) :: Nil, irrefutable(fun)) else - Prod(pat.tpe.stripAnnots, fun.tpe, fun.symbol, pats.map(project), irrefutable(fun)) + Prod(erase(pat.tpe.stripAnnots), fun.tpe, fun.symbol, pats.map(project), irrefutable(fun)) case Typed(pat @ UnApply(_, _, _), _) => project(pat) case Typed(expr, tpt) => Typ(erase(expr.tpe.stripAnnots), true) diff --git a/tests/patmat/enum-approx.check b/tests/patmat/enum-approx.check new file mode 100644 index 000000000000..c699a9b1a3a4 --- /dev/null +++ b/tests/patmat/enum-approx.check @@ -0,0 +1 @@ +24: Pattern Match Exhaustivity: Fun.ConstNullClass(_) diff --git a/tests/patmat/enum-approx.scala b/tests/patmat/enum-approx.scala new file mode 100644 index 000000000000..5fbe0b75b01b --- /dev/null +++ b/tests/patmat/enum-approx.scala @@ -0,0 +1,31 @@ +enum Fun[-T, +U >: Null] { + def f: T => U = this match { + case Identity(g) => g + case ConstNull => (_ => null) + case ConstNullClass(y) => (_ => null) + case ConstNullSimple => null + } + + case Identity[T, U >: Null](g: T => U) extends Fun[T, U] + case ConstNull + case ConstNullClass(x: T) + case ConstNullSimple +} + +object Test { + def main(args: Array[String]) = { + val x: Null = Fun.ConstNull.f("abc") + val y: Null = Fun.ConstNullClass("hello").f("abc") + assert(Fun.ConstNullSimple.f == null) + } + + import Fun._ + + def f[T, U >: Null](f: Fun[T, U]): T => U = f match { + case Identity(g) => g + case ConstNull => (_ => null) + case ConstNullClass(y: Int) => (_ => null) + case ConstNullSimple => null + } +} +