@@ -23,7 +23,7 @@ import ProtoTypes.*
2323import Inferencing .*
2424import reporting .*
2525import Nullables .* , NullOpsDecorator .*
26- import config .{Feature , SourceVersion }
26+ import config .{Feature , MigrationVersion , SourceVersion }
2727
2828import collection .mutable
2929import config .Printers .{overload , typr , unapp }
@@ -607,7 +607,7 @@ trait Applications extends Compatibility {
607607 fail(TypeMismatch (methType.resultType, resultType, None ))
608608
609609 // match all arguments with corresponding formal parameters
610- if success then matchArgs(orderedArgs, methType.paramInfos, 0 )
610+ if success then matchArgs(orderedArgs, methType.paramInfos, n = 0 )
611611 case _ =>
612612 if (methType.isError) ok = false
613613 else fail(em " $methString does not take parameters " )
@@ -765,13 +765,20 @@ trait Applications extends Compatibility {
765765 }
766766 else defaultArgument(normalizedFun, n, testOnly)
767767
768+ // a bug allowed empty parens to expand to implicit args, offer rewrite only on migration
769+ def canSupplyImplicits = methodType.isImplicitMethod
770+ && (applyKind == ApplyKind .Using || {
771+ if args1.isEmpty then
772+ fail(MissingImplicitParameterInEmptyArguments (methodType.paramNames(n), methString))
773+ true
774+ })
775+ && ctx.mode.is(Mode .ImplicitsEnabled )
776+
768777 if ! defaultArg.isEmpty then
769778 defaultArg.tpe.widen match
770779 case _ : MethodOrPoly if testOnly => matchArgs(args1, formals1, n + 1 )
771780 case _ => matchArgs(args1, addTyped(treeToArg(defaultArg)), n + 1 )
772- else if (methodType.isContextualMethod || applyKind == ApplyKind .Using && methodType.isImplicitMethod)
773- && ctx.mode.is(Mode .ImplicitsEnabled )
774- then
781+ else if methodType.isContextualMethod && ctx.mode.is(Mode .ImplicitsEnabled ) || canSupplyImplicits then
775782 val implicitArg = implicitArgTree(formal, appPos.span)
776783 matchArgs(args1, addTyped(treeToArg(implicitArg)), n + 1 )
777784 else
@@ -1149,32 +1156,53 @@ trait Applications extends Compatibility {
11491156 }
11501157 }
11511158
1159+ def tryWithUsing (fun1 : Tree , proto : FunProto )(using Context ): Option [Tree ] =
1160+ tryEither(Option (simpleApply(fun1, proto.withApplyKind(ApplyKind .Using )))): (_, _) =>
1161+ None
1162+
11521163 /** If the applied function is an automatically inserted `apply`
1153- * method and one of its arguments has a type mismatch , append
1154- * a note to the error message that explains where the required
1155- * type comes from. See #19680 and associated test case.
1164+ * method and one of its arguments has a type mismatch , append
1165+ * a note to the error message that explains where the required
1166+ * type comes from. See #19680 and associated test case.
11561167 */
11571168 def maybeAddInsertedApplyNote (failedState : TyperState , fun1 : Tree )(using Context ): Unit =
11581169 if fun1.symbol.name == nme.apply && fun1.span.isSynthetic then
11591170 fun1 match
1160- case Select (qualifier, _) =>
1161- def mapMessage (dia : Diagnostic ): Diagnostic =
1162- dia match
1163- case dia : Diagnostic .Error =>
1164- dia.msg match
1165- case msg : TypeMismatch =>
1166- msg.inTree match
1167- case Some (arg) if tree.args.exists(_.span == arg.span) =>
1168- val noteText =
1169- i """ The required type comes from a parameter of the automatically
1170- |inserted `apply` method of ` ${qualifier.tpe}`. """ .stripMargin
1171- Diagnostic .Error (msg.appendExplanation(" \n\n " + noteText), dia.pos)
1172- case _ => dia
1173- case msg => dia
1174- case dia => dia
1175- failedState.reporter.mapBufferedMessages(mapMessage)
1176- case _ => ()
1177- else ()
1171+ case Select (qualifier, _) =>
1172+ def mapMessage (dia : Diagnostic ): Diagnostic =
1173+ dia match
1174+ case dia : Diagnostic .Error =>
1175+ dia.msg match
1176+ case msg : TypeMismatch =>
1177+ msg.inTree match
1178+ case Some (arg) if tree.args.exists(_.span == arg.span) =>
1179+ val noteText =
1180+ i """ The required type comes from a parameter of the automatically
1181+ |inserted `apply` method of ` ${qualifier.tpe}`. """ .stripMargin
1182+ Diagnostic .Error (msg.appendExplanation(" \n\n " + noteText), dia.pos)
1183+ case _ => dia
1184+ case msg => dia
1185+ case dia => dia
1186+ failedState.reporter.mapBufferedMessages(mapMessage)
1187+ case _ => ()
1188+
1189+ def maybePatchBadParensForImplicit (failedState : TyperState )(using Context ): Boolean =
1190+ var retry = false
1191+ failedState.reporter.mapBufferedMessages: dia =>
1192+ dia match
1193+ case err : Diagnostic .Error =>
1194+ err.msg match
1195+ case msg : MissingImplicitParameterInEmptyArguments =>
1196+ val mv = MigrationVersion .ImplicitParamsWithoutUsing
1197+ if mv.needsPatch then
1198+ retry = true
1199+ rewrites.Rewrites .patch(tree.span.withStart(tree.span.point), " " ) // f() -> f
1200+ Diagnostic .Warning (err.msg, err.pos)
1201+ else
1202+ err
1203+ case _ => err
1204+ case dia => dia
1205+ retry
11781206
11791207 val result = fun1.tpe match {
11801208 case err : ErrorType => cpy.Apply (tree)(fun1, proto.typedArgs()).withType(err)
@@ -1231,10 +1259,13 @@ trait Applications extends Compatibility {
12311259 errorTree(tree, em " argument to summonFrom must be a pattern matching closure " )
12321260 }
12331261 else
1234- tryEither {
1235- simpleApply(fun1, proto)
1236- } {
1237- (failedVal, failedState) =>
1262+ tryEither(simpleApply(fun1, proto)): (failedVal, failedState) =>
1263+ // a bug allowed empty parens to expand to implicit args, offer rewrite only on migration, then retry
1264+ if proto.args.isEmpty && maybePatchBadParensForImplicit(failedState) then
1265+ tryWithUsing(fun1, proto).getOrElse:
1266+ failedState.commit()
1267+ failedVal
1268+ else
12381269 def fail =
12391270 maybeAddInsertedApplyNote(failedState, fun1)
12401271 failedState.commit()
@@ -1244,10 +1275,9 @@ trait Applications extends Compatibility {
12441275 // The reason we need to try both is that the decision whether to use tupled
12451276 // or not was already taken but might have to be revised when an implicit
12461277 // is inserted on the qualifier.
1247- tryWithImplicitOnQualifier(fun1, originalProto).getOrElse(
1278+ tryWithImplicitOnQualifier(fun1, originalProto).getOrElse:
12481279 if (proto eq originalProto) fail
1249- else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail))
1250- }
1280+ else tryWithImplicitOnQualifier(fun1, proto).getOrElse(fail)
12511281 }
12521282
12531283 if result.tpe.isNothingType then
0 commit comments