diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-01-31 00:33:19 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-02-07 21:58:47 +0100 |
commit | 55c9b9c280ac9bc36bbac09397c7646f8dcf4583 (patch) | |
tree | cdfc1cd396eaba78f0150968634722bcb8df8bd7 /test/files/run/t6146b.scala | |
parent | 81d8f9d3da656cfb05f125ba7cf70ca51a477240 (diff) | |
download | scala-55c9b9c280ac9bc36bbac09397c7646f8dcf4583.tar.gz scala-55c9b9c280ac9bc36bbac09397c7646f8dcf4583.tar.bz2 scala-55c9b9c280ac9bc36bbac09397c7646f8dcf4583.zip |
SI-6146 More accurate prefixes for sealed subtypes.
When analysing exhaustivity/reachability of type tests
and equality tests, the pattern matcher must construct
a set of sealed subtypes based on the prefix of the
static type of and the set of sealed descendent symbols
of that type.
Previously, it was using `memberType` for this purpose.
In simple cases, this is sufficient:
scala> class C { class I1; object O { class I2 } }; object D extends C
defined class C
defined module D
scala> typeOf[D.type] memberType typeOf[C#I1].typeSymbol
res0: u.Type = D.I1
But, as reported in this bug, it fails when there is an
additional level of nesting:
scala> typeOf[D.type] memberType typeOf[c.O.I2 forSome { val c: C }].typeSymbol
res5: u.Type = C.O.I2
This commit introduces `nestedMemberType`, which uses `memberType`
recursively up the prefix chain prefix chain.
scala> nestedMemberType(typeOf[c.O.I2 forSome { val c: C }].typeSymbol, typeOf[D.type], typeOf[C].typeSymbol)
res6: u.Type = D.O.Id
Diffstat (limited to 'test/files/run/t6146b.scala')
-rw-r--r-- | test/files/run/t6146b.scala | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/files/run/t6146b.scala b/test/files/run/t6146b.scala new file mode 100644 index 0000000000..adcd40d2ee --- /dev/null +++ b/test/files/run/t6146b.scala @@ -0,0 +1,39 @@ +import scala.tools.partest.ReplTest + +class A { + sealed trait F[A] +} + +class C[T] extends A { + sealed trait F[A] + object X { + object S1 extends F[T] + } + class S2 extends F[T] +} +object O extends C[Int] { + def foo(f: F[Int]) = f match { case X.S1 => } + + class S3 extends F[Int] +} +class S4 extends O.F[String] + +object Test extends ReplTest { + override def code = """ +:power +val u = rootMirror.universe; import u._, language._ +val S1 = typeOf[c.X.S1.type forSome { val c: C[_] }].typeSymbol.tpeHK +val S2 = typeOf[O.S2].typeSymbol.tpeHK +val S3 = typeOf[O.S3].typeSymbol.tpeHK +val S4 = typeOf[S4].typeSymbol.tpeHK +val F = typeOf[c.F[_] forSome { val c: C[_] }].typeSymbol.tpeHK +val fTpe = typeOf[O.type].decl(newTermName("foo")).paramss.head.head.tpe +def memType(sub: Type, scrut: Type): Type = + nestedMemberType(sub.typeSymbol, scrut.prefix, scrut.typeSymbol.owner) + +memType(S1, fTpe) +memType(S2, fTpe) +memType(S3, fTpe) +memType(S4, fTpe) + """.stripMargin.trim +}
\ No newline at end of file |