aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-17 20:41:13 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-17 20:42:34 +0200
commit7c0c1f31fda704e790ca7a9d260c8c956b28d447 (patch)
tree6341947156c34e905f0a845a75d6056771e11d9a /src/dotty/tools/dotc/typer/Applications.scala
parentdfa32801f5b2c774a8c792353c1bf1d1781a4a0e (diff)
downloaddotty-7c0c1f31fda704e790ca7a9d260c8c956b28d447.tar.gz
dotty-7c0c1f31fda704e790ca7a9d260c8c956b28d447.tar.bz2
dotty-7c0c1f31fda704e790ca7a9d260c8c956b28d447.zip
Fix typing of match expressions
Allow matches between unapply types and selector type where a possible overlap might exist.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 6e78a570d..f7a96c6b4 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -740,13 +740,19 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
def fromScala2x = unapplyFn.symbol.exists && (unapplyFn.symbol.owner is Scala2x)
- /** Can `subtp` be made to be a subtype of `tp`, possibly by dropping some
- * refinements in `tp`?
+ /** Is `subtp` a subtype of `tp` or of some generalization of `tp`?
+ * The generalizations of a type T are the smallest set G such that
+ *
+ * - T is in G
+ * - If a typeref R in G represents a trait, R's superclass is in G.
+ * - If a type proxy P is not a reference to a class, P's supertype is in G
*/
def isSubTypeOfParent(subtp: Type, tp: Type)(implicit ctx: Context): Boolean =
if (subtp <:< tp) true
else tp match {
- case tp: RefinedType => isSubTypeOfParent(subtp, tp.parent)
+ case tp: TypeRef if tp.symbol.isClass =>
+ tp.symbol.is(Trait) && isSubTypeOfParent(subtp, tp.parents.head)
+ case tp: TypeProxy => isSubTypeOfParent(subtp, tp.superType)
case _ => false
}
@@ -754,13 +760,11 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case mt: MethodType if mt.paramTypes.length == 1 =>
val unapplyArgType = mt.paramTypes.head
unapp.println(i"unapp arg tpe = $unapplyArgType, pt = $selType")
- def wpt = widenForMatchSelector(selType) // needed?
val ownType =
if (selType <:< unapplyArgType) {
- //fullyDefinedType(unapplyArgType, "extractor argument", tree.pos)
unapp.println(i"case 1 $unapplyArgType ${ctx.typerState.constraint}")
selType
- } else if (isSubTypeOfParent(unapplyArgType, wpt)(ctx.addMode(Mode.GADTflexible))) {
+ } else if (isSubTypeOfParent(unapplyArgType, selType)(ctx.addMode(Mode.GADTflexible))) {
maximizeType(unapplyArgType) match {
case Some(tvar) =>
def msg =
@@ -786,9 +790,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
unapplyArgType
} else {
unapp.println("Neither sub nor super")
- unapp.println(TypeComparer.explained(implicit ctx => unapplyArgType <:< wpt))
+ unapp.println(TypeComparer.explained(implicit ctx => unapplyArgType <:< selType))
errorType(
- d"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $wpt",
+ d"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $selType",
tree.pos)
}