Skip to content

Commit

Permalink
SI-6771 Alias awareness for checkableType in match analysis.
Browse files Browse the repository at this point in the history
Failure to dealias the type of the scrutinee led the pattern
matcher to incorrectly reason about the type test in:

   type Id[X] = X; (null: Id[Option[Int]]) match { case Some(_) => }

Before, `checkableType` returned `Id[?]`, now it returns `Some[?]`.
  • Loading branch information
retronym committed Apr 24, 2013
1 parent 4dcb33e commit 3009916
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ trait TreeAndTypeAnalysis extends Debugging {
// TODO: when type tags are available, we will check -- when this is implemented, can we take that into account here?
// similar to typer.infer.approximateAbstracts
object typeArgsToWildcardsExceptArray extends TypeMap {
def apply(tp: Type): Type = tp match {
// SI-6771 dealias would be enough today, but future proofing with the dealiasWiden.
// See neg/t6771b.scala for elaboration
def apply(tp: Type): Type = tp.dealiasWiden match {
case TypeRef(pre, sym, args) if args.nonEmpty && (sym ne ArrayClass) =>
TypeRef(pre, sym, args map (_ => WildcardType))
case _ =>
Expand Down
6 changes: 6 additions & 0 deletions test/files/neg/t6771b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
t6771b.scala:14: error: type mismatch;
found : x.type (with underlying type String)
required: Test.a.type
b = b match { case x => x }
^
one error found
16 changes: 16 additions & 0 deletions test/files/neg/t6771b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Currently, the pattern matcher widens the type of the
// scrutinee, so this doesn't typecheck. This test just
// confirms this behaviour, although it would be an improvement
// to change this and make this a `pos` test.
//
// But, to the intrepid hacker who works on this, a few notes:
// You'll have to look into places in the pattern matcher that
// call `dealias`, and see if they need to be `dealiasWiden`.
// For example, if `checkableType` used only `dealias`, `pos/t6671.scala`
// would fail.
object Test {
val a = ""; var b: a.type = a

b = b match { case x => x }
}

1 change: 1 addition & 0 deletions test/files/pos/t6771.flags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Xfatal-warnings
9 changes: 9 additions & 0 deletions test/files/pos/t6771.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
object Test {
type Id[X] = X
val a: Id[Option[Int]] = None

a match {
case Some(x) => println(x)
case None =>
}
}

0 comments on commit 3009916

Please sign in to comment.