Skip to content

Commit 585cf5a

Browse files
committed
SI-9401 Avoid SOE with array + missing classtag
The implicit classtags required by the Array constructor are not expressed in the type signature of its constructor, and instead are summoned by a special case in the typechecker. This special case entails replacing the `new Array` tree with `implicitly[T].newArray(size)`, handled in `ArrayInstantiation`. This tree is recursively typechecked. However, if the implicit materialization/search fails, an error is issued to the current reporter and the original tree is marked with an error type. As above, this is recursively typechecked. In the normal course of affairs, the recursive typecheck of the erroneous tree would be a noop (the tree already has a type!). However, if we are both in silent mode (in which errors are buffered) and in retyping mode (in which the typer clears the type and symbols of trees), we were getting into an cycle. In the enclosed test, retyping mode was trying to recover from: Resetting.this.gencastarray_=(new Array[T](0).<ERROR>) By inserting a suitable a view: implicitly[Resetting => { def gencastarray_=(AT)}]( Resetting.this ).gencastarray_=(new Array[T](0)) Where AT is the type found by retypechecking the argument. It is during the argument retypechecking that we fell into cycle. Crazily enough, in 2.11.0, the ensuing `StackOverflowError` was being caught and treated as a failure. We would then back out of the retyping mode, and issue the error from the the very first attempt at the implicit search. This fragile state of affairs was disrupted by a refactoring to the error reporting system in 725c5c9, after which the SOE crashed the compiler. This commit avoids recursively typechecking error typed trees.
1 parent d99785b commit 585cf5a

File tree

3 files changed

+9
-1
lines changed

3 files changed

+9
-1
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4577,7 +4577,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
45774577
typed1(atPos(tree.pos)(Block(stats, Apply(expr, args) setPos tree.pos.makeTransparent)), mode, pt)
45784578
case Apply(fun, args) =>
45794579
normalTypedApply(tree, fun, args) match {
4580-
case ArrayInstantiation(tree1) => typed(tree1, mode, pt)
4580+
case ArrayInstantiation(tree1) => if (tree1.isErrorTyped) tree1 else typed(tree1, mode, pt)
45814581
case Apply(Select(fun, nme.apply), _) if treeInfo.isSuperConstrCall(fun) => TooManyArgumentListsForConstructor(tree) //SI-5696
45824582
case tree1 => tree1
45834583
}

test/files/neg/t9401.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
t9401.scala:3: error: cannot find class tag for element type T
2+
gencastarray = new Array[T](0)
3+
^
4+
one error found

test/files/neg/t9401.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Resetting[T] {
2+
var gencastarray: Any = null
3+
gencastarray = new Array[T](0)
4+
}

0 commit comments

Comments
 (0)