Skip to content

Commit 9047880

Browse files
authored
Merge pull request #551 from scala/backport-lts-3.3-23664
Backport "Use more context for implicit search only if no default argument" to 3.3 LTS
2 parents 1d36e6e + 282f393 commit 9047880

File tree

1 file changed

+22
-17
lines changed

1 file changed

+22
-17
lines changed

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

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)