From ec5cbcc6b93f96755f7b4fa68a86cab845eca2f4 Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Thu, 11 Jul 2024 17:34:44 +0200 Subject: [PATCH 1/3] Do not crash when typing a closure with unknown type, since it can occur for erroneous input --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Typer.scala | 2 -- tests/neg/i20511-1.scala | 7 +++++++ tests/neg/i20511.scala | 8 ++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 tests/neg/i20511-1.scala create mode 100644 tests/neg/i20511.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index e28ba5fd669e..ba3f93a42b91 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1725,7 +1725,7 @@ object Parsers { case arg => arg val args1 = args.mapConserve(sanitize) - + if in.isArrow || isPureArrow || erasedArgs.contains(true) then functionRest(args) else diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index dbc9818abf23..f5f974b33c88 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1977,8 +1977,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // Polymorphic SAMs are not currently supported (#6904). EmptyTree case tp => - if !tp.isErroneous then - throw new java.lang.Error(i"internal error: closing over non-method $tp, pos = ${tree.span}") TypeTree(defn.AnyType) } else typed(tree.tpt) diff --git a/tests/neg/i20511-1.scala b/tests/neg/i20511-1.scala new file mode 100644 index 000000000000..03bd475ffafd --- /dev/null +++ b/tests/neg/i20511-1.scala @@ -0,0 +1,7 @@ +package pakiet + +def toppingPrice(size: Int): Double = ??? + +def crustPrice(crustType: Double): Double = ??? + +export toppingPrice.apply, crustPrice.unlift // error // error // error diff --git a/tests/neg/i20511.scala b/tests/neg/i20511.scala new file mode 100644 index 000000000000..657609536bf0 --- /dev/null +++ b/tests/neg/i20511.scala @@ -0,0 +1,8 @@ +package pakiet + +def toppingPrice(size: Int): Double = ??? + +def crustPrice(crustType: Double): Double = ??? + +export toppingPrice, crustPrice // error // error +val i = 1 // error From 74920d38d0e9943a8c7f1550d17d2eec97e03d6d Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Wed, 6 Nov 2024 13:33:23 +0100 Subject: [PATCH 2/3] Don't typeAhead erroneous parsing trees related to export statements --- .../src/dotty/tools/dotc/typer/Namer.scala | 2 +- tests/neg/i20511-1.check | 32 +++++++++++++++++++ tests/neg/i20511-1.scala | 2 +- tests/neg/i20511.check | 12 +++++++ 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i20511-1.check create mode 100644 tests/neg/i20511.check diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 83964417a6f1..5b8cac9b1684 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1131,7 +1131,7 @@ class Namer { typer: Typer => private def exportForwarders(exp: Export, pathMethod: Symbol)(using Context): List[tpd.MemberDef] = val buf = new mutable.ListBuffer[tpd.MemberDef] val Export(expr, selectors) = exp - if expr.isEmpty then + if expr.isEmpty || selectors.exists(_.imported.name == nme.ERROR) then report.error(em"Export selector must have prefix and `.`", exp.srcPos) return Nil diff --git a/tests/neg/i20511-1.check b/tests/neg/i20511-1.check new file mode 100644 index 000000000000..3f64940bb4fe --- /dev/null +++ b/tests/neg/i20511-1.check @@ -0,0 +1,32 @@ +-- [E083] Type Error: tests/neg/i20511-1.scala:7:7 --------------------------------------------------------------------- +7 |export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error + | ^^^^^^^^^^^^ + | Int => Double is not a valid export prefix, since it is not an immutable path + | + | longer explanation available when compiling with `-explain` +-- [E083] Type Error: tests/neg/i20511-1.scala:7:27 -------------------------------------------------------------------- +7 |export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error + | ^^^^^^^^^^ + | Any is not a valid export prefix, since it is not an immutable path + | + | longer explanation available when compiling with `-explain` +-- Error: tests/neg/i20511-1.scala:7:38 -------------------------------------------------------------------------------- +7 |export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error + | ^^^^^ + | no eligible member apply at { + | def $anonfun(crustType: Double): Double = pakiet.crustPrice(crustType) + | closure(pakiet.$anonfun:Any) + | } +-- [E083] Type Error: tests/neg/i20511-1.scala:7:45 -------------------------------------------------------------------- +7 |export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error + | ^^^^^^^^^^ + | Any is not a valid export prefix, since it is not an immutable path + | + | longer explanation available when compiling with `-explain` +-- Error: tests/neg/i20511-1.scala:7:56 -------------------------------------------------------------------------------- +7 |export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error + | ^^^^^^ + | no eligible member unlift at { + | def $anonfun(crustType: Double): Double = pakiet.crustPrice(crustType) + | closure(pakiet.$anonfun:Any) + | } diff --git a/tests/neg/i20511-1.scala b/tests/neg/i20511-1.scala index 03bd475ffafd..882520b55c07 100644 --- a/tests/neg/i20511-1.scala +++ b/tests/neg/i20511-1.scala @@ -4,4 +4,4 @@ def toppingPrice(size: Int): Double = ??? def crustPrice(crustType: Double): Double = ??? -export toppingPrice.apply, crustPrice.unlift // error // error // error +export toppingPrice.apply, crustPrice.apply, crustPrice.unlift // error // error // error // error // error diff --git a/tests/neg/i20511.check b/tests/neg/i20511.check new file mode 100644 index 000000000000..27c8126d43ab --- /dev/null +++ b/tests/neg/i20511.check @@ -0,0 +1,12 @@ +-- [E040] Syntax Error: tests/neg/i20511.scala:7:19 -------------------------------------------------------------------- +7 |export toppingPrice, crustPrice // error // error + | ^ + | '.' expected, but ',' found +-- [E040] Syntax Error: tests/neg/i20511.scala:8:0 --------------------------------------------------------------------- +8 |val i = 1 // error + |^^^ + |'.' expected, but 'end of statement' found +-- Error: tests/neg/i20511.scala:7:21 ---------------------------------------------------------------------------------- +7 |export toppingPrice, crustPrice // error // error + | ^^^^^^^^^^ + | Export selector must have prefix and `.` From 6e286792efd1336c3902dea567be1250a9242a3c Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Mon, 18 Nov 2024 12:46:49 +0100 Subject: [PATCH 3/3] Don't explicitly check for error trees in export selectors --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 2 +- tests/neg/i20511.check | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 5b8cac9b1684..83964417a6f1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1131,7 +1131,7 @@ class Namer { typer: Typer => private def exportForwarders(exp: Export, pathMethod: Symbol)(using Context): List[tpd.MemberDef] = val buf = new mutable.ListBuffer[tpd.MemberDef] val Export(expr, selectors) = exp - if expr.isEmpty || selectors.exists(_.imported.name == nme.ERROR) then + if expr.isEmpty then report.error(em"Export selector must have prefix and `.`", exp.srcPos) return Nil diff --git a/tests/neg/i20511.check b/tests/neg/i20511.check index 27c8126d43ab..fefff9f42a6f 100644 --- a/tests/neg/i20511.check +++ b/tests/neg/i20511.check @@ -6,7 +6,9 @@ 8 |val i = 1 // error |^^^ |'.' expected, but 'end of statement' found --- Error: tests/neg/i20511.scala:7:21 ---------------------------------------------------------------------------------- +-- [E083] Type Error: tests/neg/i20511.scala:7:21 ---------------------------------------------------------------------- 7 |export toppingPrice, crustPrice // error // error | ^^^^^^^^^^ - | Export selector must have prefix and `.` + | Any is not a valid export prefix, since it is not an immutable path + | + | longer explanation available when compiling with `-explain`