@@ -4237,8 +4237,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4237
4237
case _ =>
4238
4238
}
4239
4239
4240
- /** Convert constructor proxy reference to a new expression */
4241
- def newExpr (ctorResultType : Type ) =
4240
+ /** If `tree` is a constructor proxy reference, convert it to a `new` expression,
4241
+ * otherwise return EmptyTree.
4242
+ */
4243
+ def newExpr (tree : Tree ): Tree =
4244
+ val ctorResultType = applyProxyResultType(tree)
4245
+ if ! ctorResultType.exists then return EmptyTree
4242
4246
val qual = qualifier(tree)
4243
4247
val tpt = qual match
4244
4248
case Ident (name) =>
@@ -4257,8 +4261,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4257
4261
pt)
4258
4262
.showing(i " convert creator $tree -> $result" , typr)
4259
4263
4260
- def applyProxy (tree : Tree ) = tree match
4264
+ /** If `tree` is a constructor proxy reference, return the type it constructs,
4265
+ * otherwise return NoType.
4266
+ */
4267
+ def applyProxyResultType (tree : Tree ): Type = tree match
4261
4268
case Select (_, nme.apply) =>
4269
+ // can't use tree.symbol and tree.tpe.widen.finalResultType, because when overloaded
4270
+ // tree.symbol is NoSymbol (via MultiDenotation.symbol) and tree.tpe won't widen.
4262
4271
tree.denot.altsWith(_.isAllOf(ApplyProxyFlags )) match
4263
4272
case denot :: _ =>
4264
4273
// any of the constructors will do, in order to get the result type, so using the first one
@@ -4278,9 +4287,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4278
4287
if needsTupledDual(ref, pt) && Feature .autoTuplingEnabled =>
4279
4288
adapt(tree, pt.tupledDual, locked)
4280
4289
case _ =>
4281
- val ctorResultType = applyProxy(tree)
4282
- if ctorResultType.exists then newExpr(ctorResultType)
4283
- else adaptOverloaded(ref)
4290
+ newExpr(tree).orElse(adaptOverloaded(ref))
4284
4291
}
4285
4292
case poly : PolyType
4286
4293
if ! (ctx.mode is Mode .Type ) && dummyTreeOfType.unapply(tree).isEmpty =>
@@ -4289,24 +4296,21 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
4289
4296
// Test case was but i18695.scala, but it got fixed by a different tweak in #18719.
4290
4297
// We leave test for this condition in as a defensive measure in case
4291
4298
// it arises somewhere else.
4292
- val ctorResultType = applyProxy(tree)
4293
- if ctorResultType.exists then newExpr(ctorResultType)
4294
- else if pt.isInstanceOf [PolyProto ] then tree
4295
- else
4296
- var typeArgs = tree match
4297
- case Select (qual, nme.CONSTRUCTOR ) => qual.tpe.widenDealias.argTypesLo.map(TypeTree (_))
4298
- case _ => Nil
4299
- if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree))
4300
- convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs)))
4299
+ newExpr(tree).orElse:
4300
+ if pt.isInstanceOf [PolyProto ] then tree
4301
+ else
4302
+ var typeArgs = tree match
4303
+ case Select (qual, nme.CONSTRUCTOR ) => qual.tpe.widenDealias.argTypesLo.map(TypeTree (_))
4304
+ case _ => Nil
4305
+ if typeArgs.isEmpty then typeArgs = constrained(poly, tree)._2.map(_.wrapInTypeTree(tree))
4306
+ convertNewGenericArray(readapt(tree.appliedToTypeTrees(typeArgs)))
4301
4307
case wtp =>
4302
4308
val isStructuralCall = wtp.isValueType && isStructuralTermSelectOrApply(tree)
4303
4309
if (isStructuralCall)
4304
4310
readaptSimplified(handleStructural(tree))
4305
4311
else pt match {
4306
4312
case pt : FunProto =>
4307
- val ctorResultType = applyProxy(tree)
4308
- if ctorResultType.exists then newExpr(ctorResultType)
4309
- else adaptToArgs(wtp, pt)
4313
+ newExpr(tree).orElse(adaptToArgs(wtp, pt))
4310
4314
case pt : PolyProto if ! wtp.isImplicitMethod =>
4311
4315
tryInsertApplyOrImplicit(tree, pt, locked)(tree) // error will be reported in typedTypeApply
4312
4316
case _ =>
0 commit comments