From 05cf8f60e3010c09539e8f1d7c7860eaeeb9ff0b Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Fri, 20 Apr 2018 18:37:04 +0200 Subject: [PATCH] Fix #4323: allow narrowing of class type parameters in pattern match --- compiler/src/dotty/tools/dotc/config/Settings.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 +- tests/pos/i4323.scala | 9 +++++++++ tests/pos/i4323b.scala | 13 +++++++++++++ tests/pos/i4323c.scala | 11 +++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/pos/i4323.scala create mode 100644 tests/pos/i4323b.scala create mode 100644 tests/pos/i4323c.scala diff --git a/compiler/src/dotty/tools/dotc/config/Settings.scala b/compiler/src/dotty/tools/dotc/config/Settings.scala index 6343341b29f4..6240cfc3ba48 100644 --- a/compiler/src/dotty/tools/dotc/config/Settings.scala +++ b/compiler/src/dotty/tools/dotc/config/Settings.scala @@ -137,7 +137,7 @@ object Settings { else update((argRest split ",").toList, args) case (StringTag, _) if choices.nonEmpty => if (argRest.isEmpty) missingArg - else if (!choices.contains(argRest)) + else if (!choices.contains(argRest.asInstanceOf[T])) fail(s"$arg is not a valid choice for $name", args) else update(argRest, args) case (StringTag, arg :: args) if name == "-d" => diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index fcba55cf99d4..038ea32f20e7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -984,7 +984,7 @@ class Typer extends Namer val accu = new TypeAccumulator[Set[Symbol]] { def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = { val tsyms1 = t match { - case tr: TypeRef if (tr.symbol is TypeParam) && tr.symbol.owner.isTerm && variance == 0 => + case tr: TypeRef if (tr.symbol is TypeParam) && variance == 0 => tsyms + tr.symbol case _ => tsyms diff --git a/tests/pos/i4323.scala b/tests/pos/i4323.scala new file mode 100644 index 000000000000..4ef22d44511e --- /dev/null +++ b/tests/pos/i4323.scala @@ -0,0 +1,9 @@ +enum Expr[T] { + case IExpr(value: Int) extends Expr[Int] + case BExpr(value: Boolean) extends Expr[Boolean] + + def join(other: Expr[T]): Expr[T] = (this, other) match { + case (IExpr(i1), IExpr(i2)) => IExpr(i1 + i2) + case (BExpr(b1), BExpr(b2)) => BExpr(b1 & b2) + } +} diff --git a/tests/pos/i4323b.scala b/tests/pos/i4323b.scala new file mode 100644 index 000000000000..7d5c72b8522e --- /dev/null +++ b/tests/pos/i4323b.scala @@ -0,0 +1,13 @@ +sealed trait Expr[T] { + import Expr._ + + def join(other: Expr[T]): Expr[T] = (this, other) match { + case (IExpr(i1), IExpr(i2)) => IExpr(i1 + i2) + case (BExpr(b1), BExpr(b2)) => BExpr(b1 & b2) + } +} + +object Expr { + case class IExpr(value: Int) extends Expr[Int] + case class BExpr(value: Boolean) extends Expr[Boolean] +} diff --git a/tests/pos/i4323c.scala b/tests/pos/i4323c.scala new file mode 100644 index 000000000000..eaf38d48e325 --- /dev/null +++ b/tests/pos/i4323c.scala @@ -0,0 +1,11 @@ +sealed trait Expr[T] { outer => + class Inner { + def join(other: Expr[T]): Expr[T] = (outer, other) match { + case (IExpr(i1), IExpr(i2)) => IExpr(i1 + i2) + case (BExpr(b1), BExpr(b2)) => BExpr(b1 & b2) + } + } +} + +case class IExpr(value: Int) extends Expr[Int] +case class BExpr(value: Boolean) extends Expr[Boolean]