Skip to content

Commit 53c7472

Browse files
authored
Use more context for implicit search only if no default argument (#23664)
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. Based on #23659 This might fix #23610
2 parents 22f0f6c + 975c988 commit 53c7472

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
// Try to constrain the result using `pt1`, but back out if a BadTyperStateAssertion
43724378
// is thrown. TODO Find out why the bad typer state arises and prevent it. The try-catch
@@ -4388,15 +4394,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43884394
case failed: AmbiguousImplicits =>
43894395
arg :: implicitArgs(formals1, argIndex + 1, pt)
43904396
case failed: SearchFailureType =>
4391-
lazy val defaultArg = findDefaultArgument(argIndex)
4392-
.showing(i"default argument: for $formal, $tree, $argIndex = $result", typr)
4393-
if !hasDefaultParams || defaultArg.isEmpty then
4394-
// no need to search further, the adapt fails in any case
4395-
// the reason why we continue inferring arguments in case of an AmbiguousImplicits
4396-
// is that we need to know whether there are further errors.
4397-
// If there are none, we have to propagate the ambiguity to the caller.
4398-
arg :: formals1.map(dummyArg)
4399-
else
4397+
if argHasDefault then
44004398
// This is tricky. On the one hand, we need the defaultArg to
44014399
// correctly type subsequent formal parameters in the same using
44024400
// clause in case there are parameter dependencies. On the other hand,
@@ -4407,6 +4405,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
44074405
// `if propFail.exists` where we re-type the whole using clause with named
44084406
// arguments for all implicits that were found.
44094407
arg :: inferArgsAfter(defaultArg)
4408+
else
4409+
// no need to search further, the adapt fails in any case
4410+
// the reason why we continue inferring arguments in case of an AmbiguousImplicits
4411+
// is that we need to know whether there are further errors.
4412+
// If there are none, we have to propagate the ambiguity to the caller.
4413+
arg :: formals1.map(dummyArg)
44104414
case _ =>
44114415
arg :: inferArgsAfter(arg)
44124416
end implicitArgs

0 commit comments

Comments
 (0)