Skip to content

Commit 4dd0691

Browse files
oderskyWojciechMazur
authored andcommitted
Use more context for implicit search only if no default argument
After an "implicit not found", we type additional arguments to get more context which might give a larger implicit scope to search. With this commit we do that only if there is no default argument for the implicit. This might fix #23610 [Cherry-picked 975c988]
1 parent c31e1b7 commit 4dd0691

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4362,11 +4362,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43624362

43634363
val arg = inferImplicitArg(formal, tree.span.endPos)
43644364

4365+
lazy val defaultArg = findDefaultArgument(argIndex)
4366+
.showing(i"default argument: for $formal, $tree, $argIndex = $result", typr)
4367+
def argHasDefault = hasDefaultParams && !defaultArg.isEmpty
4368+
43654369
def canProfitFromMoreConstraints =
43664370
arg.tpe.isInstanceOf[AmbiguousImplicits]
4367-
// ambiguity could be decided by more constraints
4368-
|| !isFullyDefined(formal, ForceDegree.none)
4369-
// more context might constrain type variables which could make implicit scope larger
4371+
// Ambiguity could be decided by more constraints
4372+
|| !isFullyDefined(formal, ForceDegree.none) && !argHasDefault
4373+
// More context might constrain type variables which could make implicit scope larger.
4374+
// But in this case we should search with additional arguments typed only if there
4375+
// is no default argument.
43704376

43714377
arg.tpe match
43724378
case failed: SearchFailureType if canProfitFromMoreConstraints =>
@@ -4379,15 +4385,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43794385
case failed: AmbiguousImplicits =>
43804386
arg :: implicitArgs(formals1, argIndex + 1, pt)
43814387
case failed: SearchFailureType =>
4382-
lazy val defaultArg = findDefaultArgument(argIndex)
4383-
.showing(i"default argument: for $formal, $tree, $argIndex = $result", typr)
4384-
if !hasDefaultParams || defaultArg.isEmpty then
4385-
// no need to search further, the adapt fails in any case
4386-
// the reason why we continue inferring arguments in case of an AmbiguousImplicits
4387-
// is that we need to know whether there are further errors.
4388-
// If there are none, we have to propagate the ambiguity to the caller.
4389-
arg :: formals1.map(dummyArg)
4390-
else
4388+
if argHasDefault then
43914389
// This is tricky. On the one hand, we need the defaultArg to
43924390
// correctly type subsequent formal parameters in the same using
43934391
// clause in case there are parameter dependencies. On the other hand,
@@ -4398,6 +4396,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43984396
// `if propFail.exists` where we re-type the whole using clause with named
43994397
// arguments for all implicits that were found.
44004398
arg :: inferArgsAfter(defaultArg)
4399+
else
4400+
// no need to search further, the adapt fails in any case
4401+
// the reason why we continue inferring arguments in case of an AmbiguousImplicits
4402+
// is that we need to know whether there are further errors.
4403+
// If there are none, we have to propagate the ambiguity to the caller.
4404+
arg :: formals1.map(dummyArg)
44014405
case _ =>
44024406
arg :: inferArgsAfter(arg)
44034407
end implicitArgs

0 commit comments

Comments
 (0)