@@ -3836,6 +3836,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3836
3836
3837
3837
def addImplicitArgs (using Context ) =
3838
3838
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 )
3839
3845
def implicitArgs (formals : List [Type ], argIndex : Int , pt : Type ): List [Tree ] = formals match
3840
3846
case Nil => Nil
3841
3847
case formal :: formals1 =>
@@ -3851,11 +3857,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3851
3857
3852
3858
val arg = inferImplicitArg(formal, tree.span.endPos)
3853
3859
3860
+ lazy val defaultArg = findDefaultArgument(argIndex)
3861
+ .showing(i " default argument: for $formal, $tree, $argIndex = $result" , typr)
3862
+ def argHasDefault = hasDefaultParams && ! defaultArg.isEmpty
3863
+
3854
3864
def canProfitFromMoreConstraints =
3855
3865
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.
3859
3871
3860
3872
arg.tpe match
3861
3873
case failed : SearchFailureType if canProfitFromMoreConstraints =>
@@ -3868,20 +3880,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3868
3880
case failed : AmbiguousImplicits =>
3869
3881
arg :: implicitArgs(formals1, argIndex + 1 , pt)
3870
3882
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
3885
3884
// This is tricky. On the one hand, we need the defaultArg to
3886
3885
// correctly type subsequent formal parameters in the same using
3887
3886
// clause in case there are parameter dependencies. On the other hand,
@@ -3892,6 +3891,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
3892
3891
// `if propFail.exists` where we re-type the whole using clause with named
3893
3892
// arguments for all implicits that were found.
3894
3893
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)
3895
3900
case _ =>
3896
3901
arg :: inferArgsAfter(arg)
3897
3902
end implicitArgs
0 commit comments