From 54fab4d0199d6eb950e3305b36b9c3ec0e8ed75f Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Tue, 8 May 2018 11:08:38 +0200
Subject: [PATCH 1/2] Band-aidy fix for ClassCastException on malformed
programs
To typecheck
```scala
class Foo extends someTree
```
we need to detect correctly if `someTree` should be typechecked as a term or a
type; `Int => 1` should be typechecked as a type, even though it looks like a
term according to `isTerm`.
Really, we shouldn't use isType at all, because the user might write a type in
place of a term or viceversa. I think we only want to know this is a constructor
call or a type; and maybe we should just let the parser tell us which, since it
knows.
---
compiler/src/dotty/tools/dotc/typer/Typer.scala | 8 +++++++-
tests/neg/parser-stability-25.scala | 15 +++++++++++++++
tests/neg/parser-stability-26.scala | 2 ++
tests/neg/parser-stability-27.scala | 2 ++
tests/pos/singleton-fun-types.scala | 4 ++++
5 files changed, 30 insertions(+), 1 deletion(-)
create mode 100644 tests/neg/parser-stability-25.scala
create mode 100644 tests/neg/parser-stability-26.scala
create mode 100644 tests/neg/parser-stability-27.scala
create mode 100644 tests/pos/singleton-fun-types.scala
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 03d33f330927..fab1ed966237 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1593,7 +1593,13 @@ class Typer extends Namer
val seenParents = mutable.Set[Symbol]()
def typedParent(tree: untpd.Tree): Tree = {
- var result = if (tree.isType) typedType(tree)(superCtx) else typedExpr(tree)(superCtx)
+ @tailrec
+ def isTreeType(t: untpd.Tree): Boolean = t match {
+ case _: untpd.Function => true
+ case untpd.Parens(t1) => isTreeType(t1)
+ case _ => tree.isType
+ }
+ var result = if (isTreeType(tree)) typedType(tree)(superCtx) else typedExpr(tree)(superCtx)
val psym = result.tpe.dealias.typeSymbol
if (seenParents.contains(psym) && !cls.isRefinementClass) {
if (!ctx.isAfterTyper) ctx.error(i"$psym is extended twice", tree.sourcePos)
diff --git a/tests/neg/parser-stability-25.scala b/tests/neg/parser-stability-25.scala
new file mode 100644
index 000000000000..23db4498af0e
--- /dev/null
+++ b/tests/neg/parser-stability-25.scala
@@ -0,0 +1,15 @@
+class A extends (Int => i1) // error
+class B extends (Int => this) // error
+trait C {
+ val bar: Int => this // error
+}
+
+// Test that function types ending in SIP-23 singleton types are understood correctly.
+
+class D extends (Int => 1) {
+ def apply(x: Int) = 2 // error
+}
+
+class Wrap(x: Int)
+class E extends (Wrap)( // error
+// error
\ No newline at end of file
diff --git a/tests/neg/parser-stability-26.scala b/tests/neg/parser-stability-26.scala
new file mode 100644
index 000000000000..dd2c00d5c5b9
--- /dev/null
+++ b/tests/neg/parser-stability-26.scala
@@ -0,0 +1,2 @@
+// Test that function types ending in SIP-23 singleton types are understood correctly.
+class E extends (Int => 1) // error
diff --git a/tests/neg/parser-stability-27.scala b/tests/neg/parser-stability-27.scala
new file mode 100644
index 000000000000..ed841d95c08b
--- /dev/null
+++ b/tests/neg/parser-stability-27.scala
@@ -0,0 +1,2 @@
+class F extends (Int => 1)( // error
+// error
\ No newline at end of file
diff --git a/tests/pos/singleton-fun-types.scala b/tests/pos/singleton-fun-types.scala
new file mode 100644
index 000000000000..dd2f8525c9c4
--- /dev/null
+++ b/tests/pos/singleton-fun-types.scala
@@ -0,0 +1,4 @@
+trait C extends (Int => 1)
+class D extends (Int => 1) {
+ def apply(x: Int) = 1
+}
From 2732c6b3d58b11a1ba563357df56524d56428961 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Tue, 15 Jan 2019 20:46:56 +0100
Subject: [PATCH 2/2] Address review comments and use alternative fix
---
compiler/src/dotty/tools/dotc/typer/Typer.scala | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index fab1ed966237..4fbeb406351d 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1593,11 +1593,9 @@ class Typer extends Namer
val seenParents = mutable.Set[Symbol]()
def typedParent(tree: untpd.Tree): Tree = {
- @tailrec
def isTreeType(t: untpd.Tree): Boolean = t match {
- case _: untpd.Function => true
- case untpd.Parens(t1) => isTreeType(t1)
- case _ => tree.isType
+ case _: untpd.Apply => false
+ case _ => true
}
var result = if (isTreeType(tree)) typedType(tree)(superCtx) else typedExpr(tree)(superCtx)
val psym = result.tpe.dealias.typeSymbol