Skip to content

Commit cd9fdf9

Browse files
committed
Better band-aidy fix for ClassCastException on malformed programs
This patch addressed the problem at a better point I think: 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. Update: we don't crash any more on the above example for some reasons, but we still have crashes.
1 parent 615fdc9 commit cd9fdf9

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,7 +1586,13 @@ class Typer extends Namer
15861586
val seenParents = mutable.Set[Symbol]()
15871587

15881588
def typedParent(tree: untpd.Tree): Tree = {
1589-
var result = if (tree.isType) typedType(tree)(superCtx) else typedExpr(tree)(superCtx)
1589+
@tailrec
1590+
def isTreeType(t: untpd.Tree): Boolean = t match {
1591+
case _: untpd.Function => true
1592+
case untpd.Parens(t1) => isTreeType(t1)
1593+
case _ => tree.isType
1594+
}
1595+
var result = if (isTreeType(tree)) typedType(tree)(superCtx) else typedExpr(tree)(superCtx)
15901596
val psym = result.tpe.dealias.typeSymbol
15911597
if (seenParents.contains(psym) && !cls.isRefinementClass) {
15921598
if (!ctx.isAfterTyper) ctx.error(i"$psym is extended twice", tree.pos)

tests/neg/parser-stability-25.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class A extends (Int => i1) // error
2+
class B extends (Int => this) // error
3+
trait C {
4+
val bar: Int => this // error
5+
}
6+
7+
// Test that function types ending in SIP-23 singleton types are understood correctly.
8+
9+
class D extends (Int => 1) {
10+
def apply(x: Int) = 2 // error
11+
}

tests/neg/parser-stability-26.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Test that function types ending in SIP-23 singleton types are understood correctly.
2+
class E extends (Int => 1) // error

tests/pos/singleton-fun-types.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait C extends (Int => 1)
2+
class D extends (Int => 1) {
3+
def apply(x: Int) = 1
4+
}

0 commit comments

Comments
 (0)