diff options
author | odersky <odersky@gmail.com> | 2016-07-18 17:30:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-18 17:30:08 +0200 |
commit | 61aa3d9efb31182d83f4b5f6bb7f5788da5b111c (patch) | |
tree | 39289dc966fc8aad5eb3d1ed4c22672d97116862 | |
parent | a307a90c1a5f498087612894c3a923a299d02a66 (diff) | |
parent | 198817b3d55f3a3df4f320622e60515f05da3aa0 (diff) | |
download | dotty-61aa3d9efb31182d83f4b5f6bb7f5788da5b111c.tar.gz dotty-61aa3d9efb31182d83f4b5f6bb7f5788da5b111c.tar.bz2 dotty-61aa3d9efb31182d83f4b5f6bb7f5788da5b111c.zip |
Merge pull request #1399 from dotty-staging/fix-patmat-typing
Fix typing of match expressions
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 20 | ||||
-rw-r--r-- | tests/neg/i1212.scala | 1 | ||||
-rw-r--r-- | tests/neg/patmat.scala | 24 |
3 files changed, 37 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 3444b0786..69ad4f107 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.firstParent) + 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) } diff --git a/tests/neg/i1212.scala b/tests/neg/i1212.scala new file mode 100644 index 000000000..b009a4d2c --- /dev/null +++ b/tests/neg/i1212.scala @@ -0,0 +1 @@ +@ann class ann extends scala.annotation.Annotation // error: cyclic reference diff --git a/tests/neg/patmat.scala b/tests/neg/patmat.scala new file mode 100644 index 000000000..1e72c104a --- /dev/null +++ b/tests/neg/patmat.scala @@ -0,0 +1,24 @@ +trait A +trait B +class C extends A with B +case class D() +object X { + def unapply(x: B): Boolean = false +} + +object Test { + def main(args: Array[String]) = { + val ca: A = new C + ca match { + case x: B => + case X() => + case D() => // ok, but scalac disagrees + } + val cc = new C + cc match { + case x: B => + case X() => + case D() => // error: neither a subtype not a supertype + } + } +} |