From 94524371983b7adb2409c2f152a4cb2eae73a80e Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Mon, 25 Feb 2019 15:04:52 +0100 Subject: [PATCH 1/2] Fix #5970: suppress spurious warning in isInstanceOf check --- .../src/dotty/tools/dotc/core/SymDenotations.scala | 11 +++++++++++ .../dotty/tools/dotc/transform/TypeTestsCasts.scala | 1 + tests/pos-special/fatal-warnings/i5970.scala | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 tests/pos-special/fatal-warnings/i5970.scala diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index ab0e9b3ed9d4..6020df3d9e5b 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1575,6 +1575,17 @@ object SymDenotations { (symbol eq defn.NothingClass) || (symbol eq defn.NullClass) && (base ne defn.NothingClass)) + /** Is it possible that a class inherits both `this` and `that`? + * + * @note The test is based on single-class inheritance and the closed + * hierarchy of final classes. + * + * @return The result may contain false positives, but never false negatives. + */ + final def mayHaveCommonChild(that: ClassSymbol)(implicit ctx: Context): Boolean = + !this.is(Final) && !that.is(Final) && (this.is(Trait) || that.is(Trait)) || + this.derivesFrom(that) || that.derivesFrom(this.symbol) + final override def typeParamCreationFlags: FlagSet = ClassTypeParamCreationFlags /** Hook to do a pre-enter test. Overridden in PackageDenotation */ diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index dbd781357c23..392232024015 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -132,6 +132,7 @@ object TypeTestsCasts { recur(tp1, P) && recur(tp2, P) case _ => // first try withou striping type parameters for performance + !X.classSymbol.asClass.mayHaveCommonChild(P.classSymbol.asClass) || isClassDetermined(X, tpe)(ctx.fresh.setNewTyperState()) || isClassDetermined(stripTypeParam(X), tpe)(ctx.fresh.setNewTyperState()) } diff --git a/tests/pos-special/fatal-warnings/i5970.scala b/tests/pos-special/fatal-warnings/i5970.scala new file mode 100644 index 000000000000..51adb8cd0535 --- /dev/null +++ b/tests/pos-special/fatal-warnings/i5970.scala @@ -0,0 +1,12 @@ +object Test extends App { + case class Foo[T](t: T) + + def foo[T](ft: Unit|Foo[T]): T = { + ft match { + case Foo(t) => t + case () => ??? + } + } + + foo(Foo(23)) +} From e8b7038e5ce3c6b6345f519f76b6e9c797e8b640 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Mon, 25 Feb 2019 15:55:16 +0100 Subject: [PATCH 2/2] Fix CI --- compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 392232024015..b14024e933c5 100644 --- a/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -132,7 +132,7 @@ object TypeTestsCasts { recur(tp1, P) && recur(tp2, P) case _ => // first try withou striping type parameters for performance - !X.classSymbol.asClass.mayHaveCommonChild(P.classSymbol.asClass) || + X.classSymbol.exists && P.classSymbol.exists && !X.classSymbol.asClass.mayHaveCommonChild(P.classSymbol.asClass) || isClassDetermined(X, tpe)(ctx.fresh.setNewTyperState()) || isClassDetermined(stripTypeParam(X), tpe)(ctx.fresh.setNewTyperState()) }