Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Decorators.*
import Denotations.*, SymDenotations.*
import DenotTransformers.*
import NullOpsDecorator.*
import util.Spans.Span

object ElimRepeated {
val name: String = "elimRepeated"
Expand Down Expand Up @@ -183,15 +184,16 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
.get
.symbol.asTerm
// Generate the method
val forwarderDef = DefDef(forwarderSym, prefss => {
val forwarderDef = DefDef(forwarderSym, prefss =>
val init :+ (last :+ vararg) = prefss: @unchecked
// Can't call `.argTypes` here because the underlying array type is of the
// form `Array[? <: SomeType]`, so we need `.argInfos` to get the `TypeBounds`.
val elemtp = vararg.tpe.widen.argInfos.head
ref(sym.termRef)
.appliedToArgss(init)
.appliedToTermArgs(last :+ wrapArray(vararg, elemtp))
})
.withSpan(Span(tree.span.start))
).withSpan(tree.span.toSynthetic)
Thicket(tree, forwarderDef)
else
tree
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ class ForwardDepChecks extends MiniPhase:
override def transformApply(tree: Apply)(using Context): Apply =
if (isSelfConstrCall(tree))
assert(ctx.owner.isConstructor)
checkSelfConstructorCall()
if currentLevel.isInstanceOf[LevelInfo] then // ElimRepeated can introduce RHS of ctor which is not a block
checkSelfConstructorCall()
tree

override def transformNew(tree: New)(using Context): New = {
Expand Down
9 changes: 7 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3115,10 +3115,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
def checkThisConstrCall(tree: Tree): Unit = tree match
case app: Apply if untpd.isSelfConstrCall(app) =>
if !sym.is(Synthetic)
&& sym.span.exists && app.symbol.span.exists && sym.span.start <= app.symbol.span.start
&& sym.span.exists
&& app.symbol.span.exists
&& sym.span.start <= app.symbol.span.start
&& tree.span.exists && !tree.span.isSynthetic
then
report.error("secondary constructor must call a preceding constructor", app.srcPos)
case Block(call :: _, _) => checkThisConstrCall(call)
case Block(call :: _, expr) =>
checkThisConstrCall(call)
checkThisConstrCall(expr)
case _ =>

checkThisConstrCall(rhs1)
Expand Down
9 changes: 9 additions & 0 deletions tests/neg/i24249.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


class C(i: Int) {
def this(s: String) = this(j = s.toInt, i = 27) // error

def this(i: Int, j: Int) = this(i + j)

def c = 42 * i
}
5 changes: 5 additions & 0 deletions tests/pos/i24249.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

import annotation.*

class Foo:
@varargs def this(x: Int*) = this()
Loading