Skip to content

Commit 2cd1092

Browse files
committed
Handle missing case for extension/conversion ambiguity
If a candidate can be both a conversion and an extension, which happens if it is overloaded, and the extension is not applicable, try the conversion.
1 parent 3188b43 commit 2cd1092

File tree

2 files changed

+16
-8
lines changed

2 files changed

+16
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,7 @@ trait Applications extends Compatibility {
20892089
*
20902090
* where <type-args> comes from `pt` if it is a (possibly ignored) PolyProto.
20912091
*/
2092-
def extMethodApply(methodRef: untpd.Tree, receiver: Tree, pt: Type)(using Context) = {
2092+
def extMethodApply(methodRef: untpd.Tree, receiver: Tree, pt: Type)(using Context): Tree = {
20932093
/** Integrate the type arguments from `currentPt` into `methodRef`, and produce
20942094
* a matching expected type.
20952095
* If `currentPt` is ignored, the new expected type will be ignored too.

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,13 +1043,21 @@ trait Implicits { self: Typer =>
10431043
}
10441044
pt match
10451045
case SelectionProto(name: TermName, mbrType, _, _) if cand.isExtension =>
1046-
val result = extMethodApply(untpd.Select(untpdGenerated, name.toExtensionName), argument, mbrType)
1047-
if !ctx.reporter.hasErrors && cand.isConversion then
1048-
val testCtx = ctx.fresh.setExploreTyperState()
1049-
tryConversion(using testCtx)
1050-
if testCtx.reporter.hasErrors then
1051-
ctx.error(em"ambiguous implicit: $generated is eligible both as an implicit conversion and as an extension method container")
1052-
result
1046+
def tryExtension(using Context) =
1047+
extMethodApply(untpd.Select(untpdGenerated, name.toExtensionName), argument, mbrType)
1048+
if cand.isConversion then
1049+
val extensionCtx, conversionCtx = ctx.fresh.setNewTyperState()
1050+
val extensionResult = tryExtension(using extensionCtx)
1051+
val conversionResult = tryConversion(using conversionCtx)
1052+
if !extensionCtx.reporter.hasErrors then
1053+
extensionCtx.typerState.commit()
1054+
if !conversionCtx.reporter.hasErrors then
1055+
ctx.error(em"ambiguous implicit: $generated is eligible both as an implicit conversion and as an extension method container")
1056+
extensionResult
1057+
else
1058+
conversionCtx.typerState.commit()
1059+
conversionResult
1060+
else tryExtension
10531061
case _ =>
10541062
tryConversion
10551063
}

0 commit comments

Comments
 (0)