From 002f9a08296c0bdc5149ced3b5e3f61d94f4f5ca Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 5 Dec 2021 14:20:18 +0100 Subject: [PATCH 1/7] Don't retypecheck erroneous arguments when fixing function Don't retypecheck erroneous arguments when trying conversions or extensions on the function part. Generally, we should avoid typechecking untyped trees several times, this can quickly explode exponentially. Fixes #12941 --- .../dotty/tools/dotc/typer/Applications.scala | 3 +- .../dotty/tools/dotc/typer/ProtoTypes.scala | 13 +++++++-- .../deprecation/t3235-minimal-v2.check | 8 ++++++ .../deprecation/t3235-minimal-v2.scala | 6 ++++ .../deprecation/t3235-minimal-v3.scala | 5 ++++ .../deprecation/t3235-minimal.check | 4 +++ .../deprecation/t3235-minimal.scala | 3 -- tests/neg/i12941.scala | 28 +++++++++++++++++++ tests/neg/i903.check | 7 +++++ tests/neg/i903.scala | 4 +++ tests/neg/zipped.check | 11 ++++++++ tests/neg/zipped.scala | 10 +++++++ tests/pos/i903.scala | 8 ------ tests/pos/zipped.scala | 8 +++--- 14 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v2.check create mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v2.scala create mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v3.scala create mode 100644 tests/neg-custom-args/deprecation/t3235-minimal.check create mode 100644 tests/neg/i12941.scala create mode 100644 tests/neg/i903.check create mode 100644 tests/neg/i903.scala create mode 100644 tests/neg/zipped.check create mode 100644 tests/neg/zipped.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index d8e9c413decb..180ff505e76c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -908,8 +908,9 @@ trait Applications extends Compatibility { * part. Return an optional value to indicate success. */ def tryWithImplicitOnQualifier(fun1: Tree, proto: FunProto)(using Context): Option[Tree] = - if (ctx.mode.is(Mode.SynthesizeExtMethodReceiver)) + if ctx.mode.is(Mode.SynthesizeExtMethodReceiver) || proto.hasErrorArg then // Suppress insertion of apply or implicit conversion on extension method receiver + // or if argument is erroneous by itself. None else tryInsertImplicitOnQualifier(fun1, proto, ctx.typerState.ownedVars) flatMap { fun2 => diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 76fcb77d8c30..d0fd943d918b 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -8,7 +8,7 @@ import Contexts._, Types._, Denotations._, Names._, StdNames._, NameOps._, Symbo import NameKinds.DepParamName import Trees._ import Constants._ -import util.{Stats, SimpleIdentityMap} +import util.{Stats, SimpleIdentityMap, SimpleIdentitySet} import Decorators._ import Uniques._ import config.Printers.typr @@ -282,6 +282,9 @@ object ProtoTypes { /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */ var typedArg: SimpleIdentityMap[untpd.Tree, Tree] = SimpleIdentityMap.empty + /** The argument that produced errors during typing */ + var errorArgs: SimpleIdentitySet[untpd.Tree] = SimpleIdentitySet.empty + /** The tupled or untupled version of this prototype, if it has been computed */ var tupledDual: Type = NoType @@ -341,6 +344,9 @@ object ProtoTypes { case _ => false } + /** Did an argument produce an error when typing? */ + def hasErrorArg = !state.errorArgs.isEmpty + private def cacheTypedArg(arg: untpd.Tree, typerFn: untpd.Tree => Tree, force: Boolean)(using Context): Tree = { var targ = state.typedArg(arg) if (targ == null) @@ -357,8 +363,11 @@ object ProtoTypes { targ = arg.withType(WildcardType) case _ => targ = typerFn(arg) - if (!ctx.reporter.hasUnreportedErrors) + if ctx.reporter.hasUnreportedErrors then + state.errorArgs += arg + else state.typedArg = state.typedArg.updated(arg, targ) + state.errorArgs -= arg } targ } diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v2.check b/tests/neg-custom-args/deprecation/t3235-minimal-v2.check new file mode 100644 index 000000000000..87a85f661f58 --- /dev/null +++ b/tests/neg-custom-args/deprecation/t3235-minimal-v2.check @@ -0,0 +1,8 @@ +-- Error: tests/neg-custom-args/deprecation/t3235-minimal-v2.scala:3:16 ------------------------------------------------ +3 | assert(math.round(123456789) == 123456789) // error + | ^^^^^^^^^^ + |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? +-- Error: tests/neg-custom-args/deprecation/t3235-minimal-v2.scala:4:16 ------------------------------------------------ +4 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // error + | ^^^^^^^^^^ + |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala b/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala new file mode 100644 index 000000000000..c56062076ee9 --- /dev/null +++ b/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala @@ -0,0 +1,6 @@ +object Test { + def main(args: Array[String]): Unit = { + assert(math.round(123456789) == 123456789) // error + assert(math.round(1234567890123456789L) == 1234567890123456789L) // error + } +} diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala b/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala new file mode 100644 index 000000000000..6af327811b5f --- /dev/null +++ b/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala @@ -0,0 +1,5 @@ +object Test { + def main(args: Array[String]): Unit = { + assert(1234567890123456789L.round == 1234567890123456789L) // error + } +} diff --git a/tests/neg-custom-args/deprecation/t3235-minimal.check b/tests/neg-custom-args/deprecation/t3235-minimal.check new file mode 100644 index 000000000000..2a4dc60b898c --- /dev/null +++ b/tests/neg-custom-args/deprecation/t3235-minimal.check @@ -0,0 +1,4 @@ +-- Error: tests/neg-custom-args/deprecation/t3235-minimal.scala:3:21 --------------------------------------------------- +3 | assert(123456789.round == 123456789) // error + | ^^^^^^^^^^^^^^^ + |method round in class RichInt is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? diff --git a/tests/neg-custom-args/deprecation/t3235-minimal.scala b/tests/neg-custom-args/deprecation/t3235-minimal.scala index 3aef0eea2dae..c09c56a329ca 100644 --- a/tests/neg-custom-args/deprecation/t3235-minimal.scala +++ b/tests/neg-custom-args/deprecation/t3235-minimal.scala @@ -1,8 +1,5 @@ object Test { def main(args: Array[String]): Unit = { assert(123456789.round == 123456789) // error - assert(math.round(123456789) == 123456789) // error - assert(1234567890123456789L.round == 1234567890123456789L) // error - assert(math.round(1234567890123456789L) == 1234567890123456789L) // error } } diff --git a/tests/neg/i12941.scala b/tests/neg/i12941.scala new file mode 100644 index 000000000000..0948cf7ce545 --- /dev/null +++ b/tests/neg/i12941.scala @@ -0,0 +1,28 @@ +object A: + def myFun(op: String ?=> Unit) = () + +@main def func: Unit = + A.myFun { + val res: String = summon[String] + println(ress) // error + } + +class I: + def runSth: Int = 1 + +abstract class A: + def myFun(op: I ?=> Unit) = + op(using I()) + 1 + +class B extends A + +def assertEquals(x: String, y: Int, z: Int): Unit = () + +@main def hello: Unit = + + B().myFun { + val res = summon[I].runSth + assertEquals("", 1, res, "asd") // error + println("Hello!") + } \ No newline at end of file diff --git a/tests/neg/i903.check b/tests/neg/i903.check new file mode 100644 index 000000000000..7e3b188dff85 --- /dev/null +++ b/tests/neg/i903.check @@ -0,0 +1,7 @@ +-- [E007] Type Mismatch Error: tests/neg/i903.scala:3:16 --------------------------------------------------------------- +3 | "".contains("", (_: Int)) // error + | ^^^^^^^^^^^^ + | Found: (String, Int) + | Required: CharSequence + +longer explanation available when compiling with `-explain` diff --git a/tests/neg/i903.scala b/tests/neg/i903.scala new file mode 100644 index 000000000000..03503ead463b --- /dev/null +++ b/tests/neg/i903.scala @@ -0,0 +1,4 @@ +object Test { + def test2 = + "".contains("", (_: Int)) // error +} diff --git a/tests/neg/zipped.check b/tests/neg/zipped.check new file mode 100644 index 000000000000..582d121cd9c3 --- /dev/null +++ b/tests/neg/zipped.check @@ -0,0 +1,11 @@ +-- [E007] Type Mismatch Error: tests/neg/zipped.scala:6:10 ------------------------------------------------------------- +6 | .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: ((Int, Int, Int)) => Int + | Required: (Int, Int, Int) => Int + +longer explanation available when compiling with `-explain` +-- [E086] Syntax Error: tests/neg/zipped.scala:9:12 -------------------------------------------------------------------- +9 | .map( x => x match { case (x, y, z) => x + y + z }) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Wrong number of parameters, expected: 3 diff --git a/tests/neg/zipped.scala b/tests/neg/zipped.scala new file mode 100644 index 000000000000..a3b3d3ddac05 --- /dev/null +++ b/tests/neg/zipped.scala @@ -0,0 +1,10 @@ +object Test { + val xs: List[Int] = ??? + + // Does not work anynore since auto(un)tupling does not work after conversions + xs.lazyZip(xs).lazyZip(xs) + .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // error + + xs.lazyZip(xs).lazyZip(xs) + .map( x => x match { case (x, y, z) => x + y + z }) // error +} \ No newline at end of file diff --git a/tests/pos/i903.scala b/tests/pos/i903.scala index 5afb6e53010c..dec98dbf2705 100644 --- a/tests/pos/i903.scala +++ b/tests/pos/i903.scala @@ -15,12 +15,4 @@ object Test { // f.apply(0) // ^ } - - def test2 = { - val f = "".contains("", (_: Int)) // dotc: - f.apply(0) - // sandbox/eta.scala:18: error: apply is not a member of Boolean(f) - // f.apply(0) - // ^ - } } diff --git a/tests/pos/zipped.scala b/tests/pos/zipped.scala index 2453b880cbc3..0d394bb953a5 100644 --- a/tests/pos/zipped.scala +++ b/tests/pos/zipped.scala @@ -23,12 +23,12 @@ object Test { .map( (x: Int, y: Int, z: Int) => x + y + z ) // OK // 4. The single parameter map works through an inserted conversion - xs.lazyZip(xs).lazyZip(xs) - .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // now also OK + //xs.lazyZip(xs).lazyZip(xs) + // .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // now also OK // 5. If we leave out the parameter type, it now works as well. - xs.lazyZip(xs).lazyZip(xs) - .map( x => x match { case (x, y, z) => x + y + z }) // now also OK + //xs.lazyZip(xs).lazyZip(xs) + // .map( x => x match { case (x, y, z) => x + y + z }) // now also OK // This means that the following works in Dotty 3.0 as well as 3.x for ((x, y, z) <- xs.lazyZip(xs).lazyZip(xs)) yield x + y + z From a3e284012ccb71e40a1312c842f0a7c892c660f0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 5 Dec 2021 16:16:40 +0100 Subject: [PATCH 2/7] Refine condition when to not typecheck again Only count errors that lead to an error type in some subtree as unrecoverable. --- compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 7 +++++-- .../deprecation/t3235-minimal-v2.check | 8 -------- .../deprecation/t3235-minimal-v2.scala | 6 ------ .../deprecation/t3235-minimal-v3.scala | 5 ----- .../neg-custom-args/deprecation/t3235-minimal.check | 12 ++++++++++++ .../neg-custom-args/deprecation/t3235-minimal.scala | 3 +++ 6 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v2.check delete mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v2.scala delete mode 100644 tests/neg-custom-args/deprecation/t3235-minimal-v3.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index d0fd943d918b..2d9258f000af 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -344,7 +344,10 @@ object ProtoTypes { case _ => false } - /** Did an argument produce an error when typing? */ + /** Did an argument produce an error when typing? This means: an error was reported + * and a tree got an error type. Errors of adaptation whree a tree has a good type + * but that type does not conform to the expected type are not counted. + */ def hasErrorArg = !state.errorArgs.isEmpty private def cacheTypedArg(arg: untpd.Tree, typerFn: untpd.Tree => Tree, force: Boolean)(using Context): Tree = { @@ -363,7 +366,7 @@ object ProtoTypes { targ = arg.withType(WildcardType) case _ => targ = typerFn(arg) - if ctx.reporter.hasUnreportedErrors then + if ctx.reporter.hasUnreportedErrors && targ.existsSubTree(_.tpe.isError) then state.errorArgs += arg else state.typedArg = state.typedArg.updated(arg, targ) diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v2.check b/tests/neg-custom-args/deprecation/t3235-minimal-v2.check deleted file mode 100644 index 87a85f661f58..000000000000 --- a/tests/neg-custom-args/deprecation/t3235-minimal-v2.check +++ /dev/null @@ -1,8 +0,0 @@ --- Error: tests/neg-custom-args/deprecation/t3235-minimal-v2.scala:3:16 ------------------------------------------------ -3 | assert(math.round(123456789) == 123456789) // error - | ^^^^^^^^^^ - |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? --- Error: tests/neg-custom-args/deprecation/t3235-minimal-v2.scala:4:16 ------------------------------------------------ -4 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // error - | ^^^^^^^^^^ - |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala b/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala deleted file mode 100644 index c56062076ee9..000000000000 --- a/tests/neg-custom-args/deprecation/t3235-minimal-v2.scala +++ /dev/null @@ -1,6 +0,0 @@ -object Test { - def main(args: Array[String]): Unit = { - assert(math.round(123456789) == 123456789) // error - assert(math.round(1234567890123456789L) == 1234567890123456789L) // error - } -} diff --git a/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala b/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala deleted file mode 100644 index 6af327811b5f..000000000000 --- a/tests/neg-custom-args/deprecation/t3235-minimal-v3.scala +++ /dev/null @@ -1,5 +0,0 @@ -object Test { - def main(args: Array[String]): Unit = { - assert(1234567890123456789L.round == 1234567890123456789L) // error - } -} diff --git a/tests/neg-custom-args/deprecation/t3235-minimal.check b/tests/neg-custom-args/deprecation/t3235-minimal.check index 2a4dc60b898c..665caab69d8d 100644 --- a/tests/neg-custom-args/deprecation/t3235-minimal.check +++ b/tests/neg-custom-args/deprecation/t3235-minimal.check @@ -2,3 +2,15 @@ 3 | assert(123456789.round == 123456789) // error | ^^^^^^^^^^^^^^^ |method round in class RichInt is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? +-- Error: tests/neg-custom-args/deprecation/t3235-minimal.scala:4:16 --------------------------------------------------- +4 | assert(math.round(123456789) == 123456789) // error + | ^^^^^^^^^^ + |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? +-- Error: tests/neg-custom-args/deprecation/t3235-minimal.scala:5:32 --------------------------------------------------- +5 | assert(1234567890123456789L.round == 1234567890123456789L) // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + |method round in class RichLong is deprecated since 2.11.0: this is an integer type; there is no reason to round it. Perhaps you meant to call this on a floating-point value? +-- Error: tests/neg-custom-args/deprecation/t3235-minimal.scala:6:16 --------------------------------------------------- +6 | assert(math.round(1234567890123456789L) == 1234567890123456789L) // error + | ^^^^^^^^^^ + |method round in package scala.math is deprecated since 2.11.0: This is an integer type; there is no reason to round it. Perhaps you meant to call this with a floating-point value? diff --git a/tests/neg-custom-args/deprecation/t3235-minimal.scala b/tests/neg-custom-args/deprecation/t3235-minimal.scala index c09c56a329ca..3aef0eea2dae 100644 --- a/tests/neg-custom-args/deprecation/t3235-minimal.scala +++ b/tests/neg-custom-args/deprecation/t3235-minimal.scala @@ -1,5 +1,8 @@ object Test { def main(args: Array[String]): Unit = { assert(123456789.round == 123456789) // error + assert(math.round(123456789) == 123456789) // error + assert(1234567890123456789L.round == 1234567890123456789L) // error + assert(math.round(1234567890123456789L) == 1234567890123456789L) // error } } From fcf2560c2605e56cd4f2311952a270593ec202d8 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 6 Dec 2021 11:48:08 +0100 Subject: [PATCH 3/7] Further refine condition when not to typecheck again This should fix the failures in spire and specs2. --- .../dotty/tools/dotc/typer/ProtoTypes.scala | 23 +++++++++++++++++-- tests/pos/specs2-failure.scala | 20 ++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/pos/specs2-failure.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 2d9258f000af..1b0beae329c9 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -350,6 +350,24 @@ object ProtoTypes { */ def hasErrorArg = !state.errorArgs.isEmpty + /** Does tree have embedded error trees that are not at the outside. + * A nested tree t1 is "at the outside" relative to a tree t2 if + * - t1 and t2 have the same span, or + * - t2 is a ascription (t22: T) and t1 is at the outside of t22 + * - t2 is a closure (...) => t22 and t1 is at the outside of t22 + */ + def hasInnerErrors(t: Tree): Boolean = t match + case Typed(expr, tpe) => hasInnerErrors(expr) + case closureDef(mdef) => hasInnerErrors(mdef.rhs) + case _ => + t.existsSubTree { t1 => + if t1.tpe.isError && t1.span.toSynthetic != t.span.toSynthetic then + typr.println(i"error subtree $t1 of $t with ${t1.tpe}, spans = ${t1.span}, ${t.span}") + true + else + false + } + private def cacheTypedArg(arg: untpd.Tree, typerFn: untpd.Tree => Tree, force: Boolean)(using Context): Tree = { var targ = state.typedArg(arg) if (targ == null) @@ -366,8 +384,9 @@ object ProtoTypes { targ = arg.withType(WildcardType) case _ => targ = typerFn(arg) - if ctx.reporter.hasUnreportedErrors && targ.existsSubTree(_.tpe.isError) then - state.errorArgs += arg + if ctx.reporter.hasUnreportedErrors then + if hasInnerErrors(targ) then + state.errorArgs += arg else state.typedArg = state.typedArg.updated(arg, targ) state.errorArgs -= arg diff --git a/tests/pos/specs2-failure.scala b/tests/pos/specs2-failure.scala new file mode 100644 index 000000000000..c705c8e283ce --- /dev/null +++ b/tests/pos/specs2-failure.scala @@ -0,0 +1,20 @@ +import util.matching.Regex +import util.matching.Regex.Match + +// Demonstrate what used to be a failure in specs2, before we refined +// the scheme when not to typecheck a function argument again. +object Test: + + extension (s: String) + + def replaceAll(pairs: (String, String)*): String = + pairs.foldLeft(s) { (res, cur) => + res.replaceAll(cur._1, cur._2) + } + + def replaceAll(exp: String, f: String => String): String = + new Regex(exp).replaceAllIn(s, (m: Match) => f(m.group(0).replace("\\", "\\\\"))) + + def replaceInsideTag(tag: String, p: (String, String)*): String = + s.replaceAll(tag, (s: String) => java.util.regex.Matcher.quoteReplacement(s.replaceAll(p*))) + From 87fc207f7ba340e5d183237d8a624bb69fae3d7d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 6 Dec 2021 12:37:47 +0100 Subject: [PATCH 4/7] Disable protoquill Protquill had to be disabled since it exhibited deeply nested errors in a function argument that went away once an enclosing function was changed with a conversion or extension, and the full argument was completely typechecked. Retype checking large bodies of code like this was never inteneded and counts as a bug in the compiler. Unfortunately, this means that some type annotations will have to be added to protoquill to make it compiler again. --- .../test/scala/dotty/communitybuild/CommunityBuildTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala index f3f0bf90188e..45b6b01cb0ff 100644 --- a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala +++ b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala @@ -75,7 +75,7 @@ class CommunityBuildTestC: // @Test def oslibWatch = projects.oslibWatch.run() @Test def playJson = projects.playJson.run() @Test def pprint = projects.pprint.run() - @Test def protoquill = projects.protoquill.run() + // @Test def protoquill = projects.protoquill.run() // needs to fix new type inference errors @Test def requests = projects.requests.run() @Test def scalacheck = projects.scalacheck.run() @Test def scalaCollectionCompat = projects.scalaCollectionCompat.run() From 4d0d2053380c4effe7a957464bec7d9bc38566a5 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 6 Dec 2021 14:47:53 +0100 Subject: [PATCH 5/7] Harden `hasInnerErrors` and fix tests --- compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 4 ++-- tests/neg/i903.check | 7 ------- tests/neg/i903.scala | 4 ---- tests/neg/zipped.check | 11 ----------- tests/neg/zipped.scala | 3 +-- tests/pos/i903.scala | 8 ++++++++ tests/pos/zipped.scala | 7 ++++--- 7 files changed, 15 insertions(+), 29 deletions(-) delete mode 100644 tests/neg/i903.check delete mode 100644 tests/neg/i903.scala delete mode 100644 tests/neg/zipped.check diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 1b0beae329c9..fcbcf179d97e 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -361,8 +361,8 @@ object ProtoTypes { case closureDef(mdef) => hasInnerErrors(mdef.rhs) case _ => t.existsSubTree { t1 => - if t1.tpe.isError && t1.span.toSynthetic != t.span.toSynthetic then - typr.println(i"error subtree $t1 of $t with ${t1.tpe}, spans = ${t1.span}, ${t.span}") + if t1.typeOpt.isError && t1.span.toSynthetic != t.span.toSynthetic then + typr.println(i"error subtree $t1 of $t with ${t1.typeOpt}, spans = ${t1.span}, ${t.span}") true else false diff --git a/tests/neg/i903.check b/tests/neg/i903.check deleted file mode 100644 index 7e3b188dff85..000000000000 --- a/tests/neg/i903.check +++ /dev/null @@ -1,7 +0,0 @@ --- [E007] Type Mismatch Error: tests/neg/i903.scala:3:16 --------------------------------------------------------------- -3 | "".contains("", (_: Int)) // error - | ^^^^^^^^^^^^ - | Found: (String, Int) - | Required: CharSequence - -longer explanation available when compiling with `-explain` diff --git a/tests/neg/i903.scala b/tests/neg/i903.scala deleted file mode 100644 index 03503ead463b..000000000000 --- a/tests/neg/i903.scala +++ /dev/null @@ -1,4 +0,0 @@ -object Test { - def test2 = - "".contains("", (_: Int)) // error -} diff --git a/tests/neg/zipped.check b/tests/neg/zipped.check deleted file mode 100644 index 582d121cd9c3..000000000000 --- a/tests/neg/zipped.check +++ /dev/null @@ -1,11 +0,0 @@ --- [E007] Type Mismatch Error: tests/neg/zipped.scala:6:10 ------------------------------------------------------------- -6 | .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: ((Int, Int, Int)) => Int - | Required: (Int, Int, Int) => Int - -longer explanation available when compiling with `-explain` --- [E086] Syntax Error: tests/neg/zipped.scala:9:12 -------------------------------------------------------------------- -9 | .map( x => x match { case (x, y, z) => x + y + z }) // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Wrong number of parameters, expected: 3 diff --git a/tests/neg/zipped.scala b/tests/neg/zipped.scala index a3b3d3ddac05..7f8909b605f3 100644 --- a/tests/neg/zipped.scala +++ b/tests/neg/zipped.scala @@ -1,9 +1,8 @@ object Test { val xs: List[Int] = ??? - // Does not work anynore since auto(un)tupling does not work after conversions xs.lazyZip(xs).lazyZip(xs) - .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // error + .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // ok xs.lazyZip(xs).lazyZip(xs) .map( x => x match { case (x, y, z) => x + y + z }) // error diff --git a/tests/pos/i903.scala b/tests/pos/i903.scala index dec98dbf2705..5afb6e53010c 100644 --- a/tests/pos/i903.scala +++ b/tests/pos/i903.scala @@ -15,4 +15,12 @@ object Test { // f.apply(0) // ^ } + + def test2 = { + val f = "".contains("", (_: Int)) // dotc: + f.apply(0) + // sandbox/eta.scala:18: error: apply is not a member of Boolean(f) + // f.apply(0) + // ^ + } } diff --git a/tests/pos/zipped.scala b/tests/pos/zipped.scala index 0d394bb953a5..a23fd62acbb0 100644 --- a/tests/pos/zipped.scala +++ b/tests/pos/zipped.scala @@ -23,10 +23,11 @@ object Test { .map( (x: Int, y: Int, z: Int) => x + y + z ) // OK // 4. The single parameter map works through an inserted conversion - //xs.lazyZip(xs).lazyZip(xs) - // .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // now also OK + xs.lazyZip(xs).lazyZip(xs) + .map( (x: (Int, Int, Int)) => x match { case (x, y, z) => x + y + z }) // now also OK - // 5. If we leave out the parameter type, it now works as well. + // 5. But if that pone is deeper nested, it does not work since we don't retypecheck + // arguments deeply. //xs.lazyZip(xs).lazyZip(xs) // .map( x => x match { case (x, y, z) => x + y + z }) // now also OK From ee015bca6340da41fa31db579636e2604f333e37 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 23 Jan 2022 18:21:32 +0100 Subject: [PATCH 6/7] Revert "Disable protoquill" This reverts commit ea8d8b66fa39a9eef3f728298525eb22e899c1fd. --- .../test/scala/dotty/communitybuild/CommunityBuildTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala index 45b6b01cb0ff..f3f0bf90188e 100644 --- a/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala +++ b/community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala @@ -75,7 +75,7 @@ class CommunityBuildTestC: // @Test def oslibWatch = projects.oslibWatch.run() @Test def playJson = projects.playJson.run() @Test def pprint = projects.pprint.run() - // @Test def protoquill = projects.protoquill.run() // needs to fix new type inference errors + @Test def protoquill = projects.protoquill.run() @Test def requests = projects.requests.run() @Test def scalacheck = projects.scalacheck.run() @Test def scalaCollectionCompat = projects.scalaCollectionCompat.run() From 89ec4605b951ea9daab2282097fb9d65c688c006 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 24 Jan 2022 11:24:17 +0100 Subject: [PATCH 7/7] Fix protoquill Cherry-pick changes from https://github.com/zio/zio-protoquill/commit/5ed25aac9440eb0fcca5d9cd828dc85728fee422 also present in https://github.com/zio/zio-quill/pull/2379. --- community-build/community-projects/protoquill | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/community-projects/protoquill b/community-build/community-projects/protoquill index 41532f2b193e..5ed25aac9440 160000 --- a/community-build/community-projects/protoquill +++ b/community-build/community-projects/protoquill @@ -1 +1 @@ -Subproject commit 41532f2b193e00aec49dd2fa46247d6cb0a6b64d +Subproject commit 5ed25aac9440eb0fcca5d9cd828dc85728fee422