diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 40a38220275b..d7f58baa94ee 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -783,6 +783,18 @@ trait Checking { else if (called.is(Trait) && !caller.mixins.contains(called)) ctx.error(i"""$called is already implemented by super${caller.superClass}, |its constructor cannot be called again""", call.sourcePos) + + if (caller.is(Module)) { + val traverser = new TreeTraverser { + def traverse(tree: Tree)(implicit ctx: Context) = tree match { + case tree: RefTree if tree.isTerm && (tree.tpe.widen.classSymbol eq caller) => + ctx.error("super constructor cannot be passed a self reference", tree.sourcePos) + case _ => + traverseChildren(tree) + } + } + traverser.traverse(call) + } } /** Check that `tpt` does not define a higher-kinded type */ diff --git a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala index 257d3ca42553..8333b376a38b 100644 --- a/compiler/src/dotty/tools/dotc/util/SourcePosition.scala +++ b/compiler/src/dotty/tools/dotc/util/SourcePosition.scala @@ -70,7 +70,7 @@ extends interfaces.SourcePosition with Showable { } /** A sentinel for a non-existing source position */ -@sharable object NoSourcePosition extends SourcePosition(NoSource, NoSpan) { +@sharable object NoSourcePosition extends SourcePosition(NoSource, NoSpan, null) { override def toString: String = "?" override def withOuter(outer: SourcePosition): SourcePosition = outer } diff --git a/tests/neg/i4659.scala b/tests/neg/i4659.scala new file mode 100644 index 000000000000..33bb6407d746 --- /dev/null +++ b/tests/neg/i4659.scala @@ -0,0 +1,11 @@ +class A(val a: A)(val b:a.T) { + type T +} + +object a0 extends A(a0)(0) { // error + type T = Int +} + +object Test extends App { + new A(a0)(1) +} \ No newline at end of file diff --git a/tests/neg/i4659b.scala b/tests/neg/i4659b.scala new file mode 100644 index 000000000000..fc37ad62f80a --- /dev/null +++ b/tests/neg/i4659b.scala @@ -0,0 +1,5 @@ +case class SourcePosition(outer: SourcePosition = NoSourcePosition) { + assert(outer != null) // crash +} + +object NoSourcePosition extends SourcePosition() // error \ No newline at end of file diff --git a/tests/run/i4659b.scala b/tests/run/i4659b.scala new file mode 100644 index 000000000000..34f71c7d7490 --- /dev/null +++ b/tests/run/i4659b.scala @@ -0,0 +1,8 @@ +case class SourcePosition(outer: SourcePosition = (NoSourcePosition: SourcePosition)) + +// The code should not compile -- currently out of reach +object NoSourcePosition extends SourcePosition() + +object Test extends App { + assert(NoSourcePosition.outer == null) +} \ No newline at end of file