Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
25 changes: 17 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4298,7 +4298,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
}

/** Convert constructor proxy reference to a new expression */
def newExpr =
def newExpr(ctorResultType: Type) =
val qual = qualifier(tree)
val tpt = qual match
case Ident(name) =>
Expand All @@ -4309,17 +4309,22 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
cpy.Ident(qual)(qual.symbol.name.sourceModuleName.toTypeName)
case _ =>
errorTree(tree, em"cannot convert from $tree to an instance creation expression")
val tycon = tree.tpe.widen.finalResultType.underlyingClassRef(refinementOK = false)
val tycon = ctorResultType.underlyingClassRef(refinementOK = false)
typed(
untpd.Select(
untpd.New(untpd.TypedSplice(tpt.withType(tycon))),
nme.CONSTRUCTOR),
pt)
.showing(i"convert creator $tree -> $result", typr)

def isApplyProxy(tree: Tree) = tree match
case Select(_, nme.apply) => tree.symbol.isAllOf(ApplyProxyFlags)
case _ => false
def applyProxy(tree: Tree) = tree match
case Select(_, nme.apply) =>
tree.denot.altsWith(_.isAllOf(ApplyProxyFlags)) match
case denot :: _ =>
// any of the constructors will do, in order to get the result type, so using the first one
denot.info.widen.finalResultType
case _ => NoType
case _ => NoType

tree match {
case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[?] | _: Closure => tree
Expand All @@ -4333,7 +4338,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
if needsTupledDual(ref, pt) && Feature.autoTuplingEnabled =>
adapt(tree, pt.tupledDual, locked)
case _ =>
adaptOverloaded(ref)
val ctorResultType = applyProxy(tree)
if ctorResultType.exists then newExpr(ctorResultType)
else adaptOverloaded(ref)
}
case poly: PolyType
if !(ctx.mode is Mode.Type) && dummyTreeOfType.unapply(tree).isEmpty =>
Expand All @@ -4342,7 +4349,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
// Test case was but i18695.scala, but it got fixed by a different tweak in #18719.
// We leave test for this condition in as a defensive measure in case
// it arises somewhere else.
if isApplyProxy(tree) then newExpr
val ctorResultType = applyProxy(tree)
if ctorResultType.exists then newExpr(ctorResultType)
else if pt.isInstanceOf[PolyProto] then tree
else
var typeArgs = tree match
Expand All @@ -4356,7 +4364,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
readaptSimplified(handleStructural(tree))
else pt match {
case pt: FunProto =>
if isApplyProxy(tree) then newExpr
val ctorResultType = applyProxy(tree)
if ctorResultType.exists then newExpr(ctorResultType)
else adaptToArgs(wtp, pt)
case pt: PolyProto if !wtp.isImplicitMethod =>
tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply
Expand Down
12 changes: 12 additions & 0 deletions tests/pos/i19201.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Person(
val firstName: String,
val lastName: String,
val birthYear: Int = -1,
val address: String = ""
):
// Works if remove this constructor
def this() = this("John", "Doe")

class Test:
def p1 = Person("First", "Last") // was: Type Error: none of the overloads.. match arguments
def p2 = Person("Josh", "Joe", 1912, "Main Street")