From dd89b006218d76a74d0185392d5e427c0867a33c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 23 Mar 2013 08:59:51 +0100 Subject: SI-7285 Fix match analysis with nested objects. The fix for SI-6146 introduced `nestedMemberType` to enumerate sealed subtypes based on the (prefixed) type of the scrutinee and the symbols of its sealed subclasses. That method needed to widen `ThisType(modSym)`s to `ModuleTypeRef(modSym)` before calling `asSeenFrom`. However, this could lead to confused in the match analysis, which sees `ModuleTypeRef` as distinct from singleton types on the same modules (after all, they aren't =:=). Spurious warnings ensued. This commit makes two changes: - conditionally re-narrow the result of `asSeenFrom` in `nestedMemberType`. - present `a.b.SomeModule.type` as `SomeModule` in warnings emitted by the pattern matcher. --- test/files/neg/t7285.check | 13 +++++++ test/files/neg/t7285.flags | 1 + test/files/neg/t7285.scala | 55 ++++++++++++++++++++++++++++++ test/files/pos/t7285a.flags | 1 + test/files/pos/t7285a.scala | 83 +++++++++++++++++++++++++++++++++++++++++++++ test/files/run/t6146b.check | 5 +-- 6 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/t7285.check create mode 100644 test/files/neg/t7285.flags create mode 100644 test/files/neg/t7285.scala create mode 100644 test/files/pos/t7285a.flags create mode 100644 test/files/pos/t7285a.scala (limited to 'test') diff --git a/test/files/neg/t7285.check b/test/files/neg/t7285.check new file mode 100644 index 0000000000..108f4292a8 --- /dev/null +++ b/test/files/neg/t7285.check @@ -0,0 +1,13 @@ +t7285.scala:15: error: match may not be exhaustive. +It would fail on the following input: (Up, Down) + (d1, d2) match { + ^ +t7285.scala:33: error: match may not be exhaustive. +It would fail on the following input: Down + (d1) match { + ^ +t7285.scala:51: error: match may not be exhaustive. +It would fail on the following input: (Up, Down) + (d1, d2) match { + ^ +three errors found diff --git a/test/files/neg/t7285.flags b/test/files/neg/t7285.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t7285.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/t7285.scala b/test/files/neg/t7285.scala new file mode 100644 index 0000000000..14121d92b1 --- /dev/null +++ b/test/files/neg/t7285.scala @@ -0,0 +1,55 @@ +sealed abstract class Base + + +object Test1 { + sealed abstract class Base + + object Base { + case object Down extends Base { + } + + case object Up extends Base { + } + + (d1: Base, d2: Base) => + (d1, d2) match { + case (Up, Up) | (Down, Down) => false + case (Down, Up) => true + } + } +} + +object Test2 { + sealed abstract class Base + + object Base { + case object Down extends Base { + } + + case object Up extends Base { + } + + (d1: Base, d2: Base) => + (d1) match { + case Test2.Base.Up => false + } + } +} + + +object Test4 { + sealed abstract class Base + + object Base { + case object Down extends Base + + case object Up extends Base + } + + import Test4.Base._ + (d1: Base, d2: Base) => + (d1, d2) match { + case (Up, Up) | (Down, Down) => false + case (Down, Test4.Base.Up) => true + } +} diff --git a/test/files/pos/t7285a.flags b/test/files/pos/t7285a.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t7285a.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/pos/t7285a.scala b/test/files/pos/t7285a.scala new file mode 100644 index 0000000000..34e79c741b --- /dev/null +++ b/test/files/pos/t7285a.scala @@ -0,0 +1,83 @@ +sealed abstract class Base + +object Test { + case object Up extends Base + + def foo(d1: Base) = + d1 match { + case Up => + } + + // Sealed subtype: ModuleTypeRef .this.Test.Up.type + // Pattern: UniqueThisType Test.this.type +} + + +object Test1 { + sealed abstract class Base + + object Base { + case object Down extends Base { + } + + case object Up extends Base { + } + + (d1: Base, d2: Base) => + (d1, d2) match { + case (Up, Up) | (Down, Down) => false + case (Down, Up) => true + case (Up, Down) => false + } + } +} + +object Test2 { + sealed abstract class Base + + object Base { + case object Down extends Base { + } + + case object Up extends Base { + } + + (d1: Base, d2: Base) => + (d1) match { + case Up | Down => false + } + } +} + +object Test3 { + sealed abstract class Base + + object Base { + case object Down extends Base + + (d1: Base, d2: Base) => + (d1, d2) match { + case (Down, Down) => false + } + } +} + +object Test4 { + sealed abstract class Base + + object Base { + case object Down extends Base { + } + + case object Up extends Base { + } + + } + import Test4.Base._ + (d1: Base, d2: Base) => + (d1, d2) match { + case (Up, Up) | (Down, Down) => false + case (Down, Test4.Base.Up) => true + case (Up, Down) => false + } +} diff --git a/test/files/run/t6146b.check b/test/files/run/t6146b.check index e08e40d9fa..49ff70697e 100644 --- a/test/files/run/t6146b.check +++ b/test/files/run/t6146b.check @@ -43,10 +43,7 @@ mt1: u.Type = O.X.S1.type scala> global.typeDeconstruct.show(mt1) res0: String = TypeRef( - pre = TypeRef( - pre = ThisType(object O) - TypeSymbol(class X extends AnyRef) - ) + pre = SingleType(pre = ThisType(object O), object X) TypeSymbol(class S1 extends C.this.F[T]) ) -- cgit v1.2.3