Skip to content

Commit 9f5b3c3

Browse files
authored
Merge pull request #6000 from dotty-staging/fix-i4659
Fix #4659: disallow reference to object itself in super calls
2 parents 5cb4a1a + cef7d87 commit 9f5b3c3

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,18 @@ trait Checking {
783783
else if (called.is(Trait) && !caller.mixins.contains(called))
784784
ctx.error(i"""$called is already implemented by super${caller.superClass},
785785
|its constructor cannot be called again""", call.sourcePos)
786+
787+
if (caller.is(Module)) {
788+
val traverser = new TreeTraverser {
789+
def traverse(tree: Tree)(implicit ctx: Context) = tree match {
790+
case tree: RefTree if tree.isTerm && (tree.tpe.widen.classSymbol eq caller) =>
791+
ctx.error("super constructor cannot be passed a self reference", tree.sourcePos)
792+
case _ =>
793+
traverseChildren(tree)
794+
}
795+
}
796+
traverser.traverse(call)
797+
}
786798
}
787799

788800
/** Check that `tpt` does not define a higher-kinded type */

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ extends interfaces.SourcePosition with Showable {
7070
}
7171

7272
/** A sentinel for a non-existing source position */
73-
@sharable object NoSourcePosition extends SourcePosition(NoSource, NoSpan) {
73+
@sharable object NoSourcePosition extends SourcePosition(NoSource, NoSpan, null) {
7474
override def toString: String = "?"
7575
override def withOuter(outer: SourcePosition): SourcePosition = outer
7676
}

tests/neg/i4659.scala

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class A(val a: A)(val b:a.T) {
2+
type T
3+
}
4+
5+
object a0 extends A(a0)(0) { // error
6+
type T = Int
7+
}
8+
9+
object Test extends App {
10+
new A(a0)(1)
11+
}

tests/neg/i4659b.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
case class SourcePosition(outer: SourcePosition = NoSourcePosition) {
2+
assert(outer != null) // crash
3+
}
4+
5+
object NoSourcePosition extends SourcePosition() // error

tests/run/i4659b.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
case class SourcePosition(outer: SourcePosition = (NoSourcePosition: SourcePosition))
2+
3+
// The code should not compile -- currently out of reach
4+
object NoSourcePosition extends SourcePosition()
5+
6+
object Test extends App {
7+
assert(NoSourcePosition.outer == null)
8+
}

0 commit comments

Comments
 (0)