From 5dae5f2953438e8a1443075b44b310965c2cf863 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 21 Feb 2017 10:28:56 +0100 Subject: [PATCH 1/3] Fix #2000: Make implicit and non-implicit functions incomparable with <:< Implicit and non-implicit functions are incomparable with <:<, but are treated as equivalent with `matches`. This means implicit and non-implicit functions of the same types override each other, but RefChecks will give an error because their types are not subtypes. Also contains a test for #2002. --- .../dotty/tools/dotc/core/TypeComparer.scala | 2 +- compiler/test/dotc/tests.scala | 1 + tests/neg/customArgs/i2002.scala | 4 ++++ tests/neg/i2000.scala | 23 +++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/neg/customArgs/i2002.scala create mode 100644 tests/neg/i2000.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 6063cbf38de3..fca11170243f 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -489,7 +489,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { case tp1 @ MethodType(_, formals1) => (tp1.signature consistentParams tp2.signature) && matchingParams(formals1, formals2, tp1.isJava, tp2.isJava) && - (!tp1.isImplicit || tp2.isImplicit) && // non-implicit functions shadow implicit ones + (tp1.isImplicit == tp2.isImplicit) && isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1)) case _ => false diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala index 7af9033640b0..6b11d8ba08b2 100644 --- a/compiler/test/dotc/tests.scala +++ b/compiler/test/dotc/tests.scala @@ -196,6 +196,7 @@ class tests extends CompilerTest { @Test def neg_nopredef = compileFile(negCustomArgs, "nopredef", List("-Yno-predef")) @Test def neg_noimports = compileFile(negCustomArgs, "noimports", List("-Yno-imports")) @Test def neg_noimpots2 = compileFile(negCustomArgs, "noimports2", List("-Yno-imports")) + @Test def neg_i2002 = compileFile(negCustomArgs, "i2002", Nil) @Test def run_all = runFiles(runDir) diff --git a/tests/neg/customArgs/i2002.scala b/tests/neg/customArgs/i2002.scala new file mode 100644 index 000000000000..5561b77b84ad --- /dev/null +++ b/tests/neg/customArgs/i2002.scala @@ -0,0 +1,4 @@ +class Test { + def foo(i: Int): Int = i + def foo(implicit i: Int): Int = i // error +} diff --git a/tests/neg/i2000.scala b/tests/neg/i2000.scala new file mode 100644 index 000000000000..aa1250f08561 --- /dev/null +++ b/tests/neg/i2000.scala @@ -0,0 +1,23 @@ +object test1 { + class C[A] { def foo(a: A) = "c" } + class D extends C[String] { override def foo(implicit s: String) = "d" } // error +} + +object test2 { + class C[A] { final def foo(a: A) = "c" } + class D extends C[String] { def foo(implicit s: String) = "d" } // error + object Test { + def main(args: Array[String]) = + new D + } +} + +object test3 { + class A { + def foo(implicit i: Int): Int = i + i + } + + class B extends A { + override def foo(i: Int): Int = i // error + } +} From 6d118770042a8453e43daff39981926529efc2ba Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 21 Feb 2017 14:05:28 +0100 Subject: [PATCH 2/3] Fix test --- compiler/test/dotc/tests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala index 6b11d8ba08b2..99cbe300e880 100644 --- a/compiler/test/dotc/tests.scala +++ b/compiler/test/dotc/tests.scala @@ -184,6 +184,7 @@ class tests extends CompilerTest { @Test def neg_autoTupling = compileFile(negCustomArgs, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil) @Test def neg_i1050 = compileFile(negCustomArgs, "i1050", List("-strict")) @Test def neg_i1240 = compileFile(negCustomArgs, "i1240")(allowDoubleBindings) + @Test def neg_i2002 = compileFile(negCustomArgs, "i2002", Nil)(allowDoubleBindings) val negTailcallDir = negDir + "tailcall/" @Test def neg_tailcall_t1672b = compileFile(negTailcallDir, "t1672b") @@ -196,7 +197,6 @@ class tests extends CompilerTest { @Test def neg_nopredef = compileFile(negCustomArgs, "nopredef", List("-Yno-predef")) @Test def neg_noimports = compileFile(negCustomArgs, "noimports", List("-Yno-imports")) @Test def neg_noimpots2 = compileFile(negCustomArgs, "noimports2", List("-Yno-imports")) - @Test def neg_i2002 = compileFile(negCustomArgs, "i2002", Nil) @Test def run_all = runFiles(runDir) From 5e53ff36f1d9ac2bd433fa01e28a194810c1be74 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 21 Feb 2017 23:28:46 +0100 Subject: [PATCH 3/3] Fix test ^ 2 --- compiler/test/dotc/tests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala index 99cbe300e880..a720f1294edd 100644 --- a/compiler/test/dotc/tests.scala +++ b/compiler/test/dotc/tests.scala @@ -184,7 +184,7 @@ class tests extends CompilerTest { @Test def neg_autoTupling = compileFile(negCustomArgs, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil) @Test def neg_i1050 = compileFile(negCustomArgs, "i1050", List("-strict")) @Test def neg_i1240 = compileFile(negCustomArgs, "i1240")(allowDoubleBindings) - @Test def neg_i2002 = compileFile(negCustomArgs, "i2002", Nil)(allowDoubleBindings) + @Test def neg_i2002 = compileFile(negCustomArgs, "i2002")(allowDoubleBindings) val negTailcallDir = negDir + "tailcall/" @Test def neg_tailcall_t1672b = compileFile(negTailcallDir, "t1672b")