@@ -3836,6 +3836,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38363836
38373837 def addImplicitArgs (using Context ) =
38383838 def hasDefaultParams = methPart(tree).symbol.hasDefaultParams
3839+ def findDefaultArgument (argIndex : Int ): Tree =
3840+ def appPart (t : Tree ): Tree = t match
3841+ case Block (_, expr) => appPart(expr)
3842+ case Inlined (_, _, expr) => appPart(expr)
3843+ case t => t
3844+ defaultArgument(appPart(tree), n = argIndex, testOnly = false )
38393845 def implicitArgs (formals : List [Type ], argIndex : Int , pt : Type ): List [Tree ] = formals match
38403846 case Nil => Nil
38413847 case formal :: formals1 =>
@@ -3851,11 +3857,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38513857
38523858 val arg = inferImplicitArg(formal, tree.span.endPos)
38533859
3860+ lazy val defaultArg = findDefaultArgument(argIndex)
3861+ .showing(i " default argument: for $formal, $tree, $argIndex = $result" , typr)
3862+ def argHasDefault = hasDefaultParams && ! defaultArg.isEmpty
3863+
38543864 def canProfitFromMoreConstraints =
38553865 arg.tpe.isInstanceOf [AmbiguousImplicits ]
3856- // ambiguity could be decided by more constraints
3857- || ! isFullyDefined(formal, ForceDegree .none)
3858- // more context might constrain type variables which could make implicit scope larger
3866+ // Ambiguity could be decided by more constraints
3867+ || ! isFullyDefined(formal, ForceDegree .none) && ! argHasDefault
3868+ // More context might constrain type variables which could make implicit scope larger.
3869+ // But in this case we should search with additional arguments typed only if there
3870+ // is no default argument.
38593871
38603872 arg.tpe match
38613873 case failed : SearchFailureType if canProfitFromMoreConstraints =>
@@ -3868,20 +3880,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38683880 case failed : AmbiguousImplicits =>
38693881 arg :: implicitArgs(formals1, argIndex + 1 , pt)
38703882 case failed : SearchFailureType =>
3871- lazy val defaultArg =
3872- def appPart (t : Tree ): Tree = t match
3873- case Block (stats, expr) => appPart(expr)
3874- case Inlined (_, _, expr) => appPart(expr)
3875- case _ => t
3876- defaultArgument(appPart(tree), argIndex, testOnly = false )
3877- .showing(i " default argument: for $formal, $tree, $argIndex = $result" , typr)
3878- if ! hasDefaultParams || defaultArg.isEmpty then
3879- // no need to search further, the adapt fails in any case
3880- // the reason why we continue inferring arguments in case of an AmbiguousImplicits
3881- // is that we need to know whether there are further errors.
3882- // If there are none, we have to propagate the ambiguity to the caller.
3883- arg :: formals1.map(dummyArg)
3884- else
3883+ if argHasDefault then
38853884 // This is tricky. On the one hand, we need the defaultArg to
38863885 // correctly type subsequent formal parameters in the same using
38873886 // clause in case there are parameter dependencies. On the other hand,
@@ -3892,6 +3891,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
38923891 // `if propFail.exists` where we re-type the whole using clause with named
38933892 // arguments for all implicits that were found.
38943893 arg :: inferArgsAfter(defaultArg)
3894+ else
3895+ // no need to search further, the adapt fails in any case
3896+ // the reason why we continue inferring arguments in case of an AmbiguousImplicits
3897+ // is that we need to know whether there are further errors.
3898+ // If there are none, we have to propagate the ambiguity to the caller.
3899+ arg :: formals1.map(dummyArg)
38953900 case _ =>
38963901 arg :: inferArgsAfter(arg)
38973902 end implicitArgs
0 commit comments