@@ -4297,8 +4297,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4297
4297
case _ =>
4298
4298
}
4299
4299
4300
- /** Convert constructor proxy reference to a new expression */
4301
- def newExpr (ctorResultType : Type ) =
4300
+ /** If `tree` is a constructor proxy reference, convert it to a `new` expression,
4301
+ * otherwise return EmptyTree.
4302
+ */
4303
+ def newExpr (tree : Tree ): Tree =
4304
+ val ctorResultType = applyProxyResultType(tree)
4305
+ if ! ctorResultType.exists then return EmptyTree
4302
4306
val qual = qualifier(tree)
4303
4307
val tpt = qual match
4304
4308
case Ident (name) =>
@@ -4317,8 +4321,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4317
4321
pt)
4318
4322
.showing(i " convert creator $tree -> $result" , typr)
4319
4323
4320
- def applyProxy (tree : Tree ) = tree match
4324
+ /** If `tree` is a constructor proxy reference, return the type it constructs,
4325
+ * otherwise return NoType.
4326
+ */
4327
+ def applyProxyResultType (tree : Tree ): Type = tree match
4321
4328
case Select (_, nme.apply) =>
4329
+ // can't use tree.symbol and tree.tpe.widen.finalResultType, because when overloaded
4330
+ // tree.symbol is NoSymbol (via MultiDenotation.symbol) and tree.tpe won't widen.
4322
4331
tree.denot.altsWith(_.isAllOf(ApplyProxyFlags )) match
4323
4332
case denot :: _ =>
4324
4333
// any of the constructors will do, in order to get the result type, so using the first one
@@ -4338,9 +4347,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4338
4347
if needsTupledDual(ref, pt) && Feature .autoTuplingEnabled =>
4339
4348
adapt(tree, pt.tupledDual, locked)
4340
4349
case _ =>
4341
- val ctorResultType = applyProxy(tree)
4342
- if ctorResultType.exists then newExpr(ctorResultType)
4343
- else adaptOverloaded(ref)
4350
+ newExpr(tree).orElse(adaptOverloaded(ref))
4344
4351
}
4345
4352
case poly : PolyType
4346
4353
if ! (ctx.mode is Mode .Type ) && dummyTreeOfType.unapply(tree).isEmpty =>
@@ -4349,24 +4356,21 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4349
4356
// Test case was but i18695.scala, but it got fixed by a different tweak in #18719.
4350
4357
// We leave test for this condition in as a defensive measure in case
4351
4358
// it arises somewhere else.
4352
- val ctorResultType = applyProxy(tree)
4353
- if ctorResultType.exists then newExpr(ctorResultType)
4354
- else if pt.isInstanceOf [PolyProto ] then tree
4355
- else
4356
- var typeArgs = tree match
4357
- case Select (qual, nme.CONSTRUCTOR ) => qual.tpe.widenDealias.argTypesLo.map(TypeTree (_))
4358
- case _ => Nil
4359
- if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree))
4360
- convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs)))
4359
+ newExpr(tree).orElse:
4360
+ if pt.isInstanceOf [PolyProto ] then tree
4361
+ else
4362
+ var typeArgs = tree match
4363
+ case Select (qual, nme.CONSTRUCTOR ) => qual.tpe.widenDealias.argTypesLo.map(TypeTree (_))
4364
+ case _ => Nil
4365
+ if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree))
4366
+ convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs)))
4361
4367
case wtp =>
4362
4368
val isStructuralCall = wtp.isValueType && isStructuralTermSelectOrApply(tree)
4363
4369
if (isStructuralCall)
4364
4370
readaptSimplified(handleStructural(tree))
4365
4371
else pt match {
4366
4372
case pt : FunProto =>
4367
- val ctorResultType = applyProxy(tree)
4368
- if ctorResultType.exists then newExpr(ctorResultType)
4369
- else adaptToArgs(wtp, pt)
4373
+ newExpr(tree).orElse(adaptToArgs(wtp, pt))
4370
4374
case pt : PolyProto if ! wtp.isImplicitMethod =>
4371
4375
tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply
4372
4376
case _ =>
0 commit comments