aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeComparer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-08-22 15:46:06 +0200
committerMartin Odersky <odersky@gmail.com>2016-08-26 11:13:15 +0200
commit23d1bfb4111d8aff513659f2b3e3dd695b9b6e03 (patch)
tree500cb526bde1bdb56707f6606c551a6c6eb573e9 /src/dotty/tools/dotc/core/TypeComparer.scala
parentf5972c7904ce802e3e7668094726c21c3a603419 (diff)
downloaddotty-23d1bfb4111d8aff513659f2b3e3dd695b9b6e03.tar.gz
dotty-23d1bfb4111d8aff513659f2b3e3dd695b9b6e03.tar.bz2
dotty-23d1bfb4111d8aff513659f2b3e3dd695b9b6e03.zip
Make expressions using GADTs type check in later phases
GADT logic is lost after PatMat. To make code typecheck, the typer should already insert casts where a subtype check succeeded because it involved bounds established by a GADT comparison.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeComparer.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 8d7e9d164..e9300c0ba 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -76,6 +76,19 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
myNothingType
}
+ /** Indicates whether a previous subtype check used GADT bounds */
+ var GADTused = false
+
+ /** Record that GADT bounds of `sym` were used in a subtype check.
+ * But exclude constructor type parameters, as these are aliased
+ * to the corresponding class parameters, which does not constitute
+ * a true usage of a GADT symbol.
+ */
+ private def GADTusage(sym: Symbol) = {
+ if (!sym.owner.isConstructor) GADTused = true
+ true
+ }
+
// Subtype testing `<:<`
def topLevelSubType(tp1: Type, tp2: Type): Boolean = {
@@ -325,7 +338,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val gbounds2 = ctx.gadt.bounds(tp2.symbol)
(gbounds2 != null) &&
(isSubTypeWhenFrozen(tp1, gbounds2.lo) ||
- narrowGADTBounds(tp2, tp1, isUpper = false))
+ narrowGADTBounds(tp2, tp1, isUpper = false)) &&
+ GADTusage(tp2.symbol)
}
((frozenConstraint || !isCappable(tp1)) && isSubType(tp1, lo2) ||
compareGADT ||
@@ -507,7 +521,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val gbounds1 = ctx.gadt.bounds(tp1.symbol)
(gbounds1 != null) &&
(isSubTypeWhenFrozen(gbounds1.hi, tp2) ||
- narrowGADTBounds(tp1, tp2, isUpper = true))
+ narrowGADTBounds(tp1, tp2, isUpper = true)) &&
+ GADTusage(tp1.symbol)
}
isSubType(hi1, tp2) || compareGADT
case _ =>