Skip to content

Commit 327327f

Browse files
committed
Cleanups
1 parent 90cb5c4 commit 327327f

File tree

3 files changed

+29
-56
lines changed

3 files changed

+29
-56
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,14 @@ object Checking {
648648
else "Cannot override non-inline parameter with an inline parameter",
649649
p1.srcPos)
650650

651+
def checkConversionsSpecific(from: Type, to: Type, pos: SrcPos)(using Context): Unit =
652+
def fail(part: String, tp: Type) =
653+
report.error(em"the $part of an implicit conversion must be more specific than $tp", pos)
654+
if to.isRef(defn.AnyValClass, skipRefined = false)
655+
|| to.isRef(defn.ObjectClass, skipRefined = false)
656+
then fail("result", to)
657+
if from.isBottomTypeAfterErasure
658+
then fail("argument", from)
651659
}
652660

653661
trait Checking {

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,13 +1027,23 @@ trait Implicits:
10271027
converted
10281028
}
10291029
pt match
1030-
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) if cand.isExtension =>
1030+
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
1031+
10311032
def tryExtension(using Context) =
10321033
extMethodApply(untpd.Select(untpdGenerated, selName), argument, mbrType)
1033-
if cand.isConversion then
1034+
1035+
def tryConversionForSelection(using Context) =
1036+
val converted = tryConversion
1037+
if !ctx.reporter.hasErrors && !selProto.isMatchedBy(converted.tpe) then
1038+
// this check is needed since adapting relative to a `SelectionProto` can succeed
1039+
// even if the term is not a subtype of the `SelectionProto`
1040+
err.typeMismatch(converted, selProto)
1041+
converted
1042+
1043+
if cand.isExtension && cand.isConversion then
10341044
val extensionCtx, conversionCtx = ctx.fresh.setNewTyperState()
10351045
val extensionResult = tryExtension(using extensionCtx)
1036-
val conversionResult = tryConversion(using conversionCtx)
1046+
val conversionResult = tryConversionForSelection(using conversionCtx)
10371047
if !extensionCtx.reporter.hasErrors then
10381048
extensionCtx.typerState.commit()
10391049
if !conversionCtx.reporter.hasErrors then
@@ -1042,7 +1052,8 @@ trait Implicits:
10421052
else
10431053
conversionCtx.typerState.commit()
10441054
conversionResult
1045-
else tryExtension
1055+
else if cand.isExtension then tryExtension
1056+
else tryConversionForSelection
10461057
case _ =>
10471058
tryConversion
10481059
}

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

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -570,19 +570,10 @@ class Typer extends Namer
570570
// try again with more defined qualifier type
571571
typedSelect(tree, pt, qual)
572572
else
573-
val tree1 =
574-
if newScheme then
575-
if dia then println(i"tryec $qual . $selName\n, pt = $pt\n, mbrProto = ${IgnoredProto(pt)}\n, compat = ${this.getClass}, locked = ${ctx.typerState.ownedVars.toList}%, %?")
576-
tryExtensionOrConversion(
577-
tree, pt, IgnoredProto(pt), qual, ctx.typerState.ownedVars, this, privateOK = true)
578-
else EmptyTree
579-
if newScheme && dia then
580-
println(i"tryec $qual . $selName\n, pt = $pt\n, mbrProto = ${IgnoredProto(pt)}\n, compat = ${this.getClass}, locked = ${ctx.typerState.ownedVars.toList}%, % = $tree1")
573+
val tree1 = tryExtensionOrConversion(
574+
tree, pt, IgnoredProto(pt), qual, ctx.typerState.ownedVars, this, privateOK = true)
581575
if !tree1.isEmpty then
582576
tree1
583-
// else if couldInstantiateTypeVar(qual.tpe.widen) then
584-
// // try again with more defined qualifier type
585-
// typedSelect(tree, pt, qual)
586577
else if qual.tpe.derivesFrom(defn.DynamicClass)
587578
&& selName.isTermName && !isDynamicExpansion(tree)
588579
then
@@ -2967,7 +2958,6 @@ class Typer extends Namer
29672958
if ctx.mode.is(Mode.ImplicitsEnabled) && qual.tpe.isValueType then
29682959
trace(i"try insert impl on qualifier $tree $pt") {
29692960
val selProto = selectionProto
2970-
//println(i"try conv $tree, $qual, ${qual.tpe}, $selProto, ${inferView(qual, selProto)}")
29712961
inferView(qual, selProto) match
29722962
case SearchSuccess(found: ExtMethodApply, _, _) =>
29732963
return found.app // nothing to check or adapt for extension method applications
@@ -3591,50 +3581,14 @@ class Typer extends Namer
35913581
case _ => ;
35923582
}
35933583

3594-
pt match
3595-
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
3596-
if newScheme then return tree
3597-
else if dia then println(i"tryec $tree, $tree . $selName\n, pt = ${mbrType.deepenProto}\n, mbrProto = $mbrType\n, compat = ${selProto.compat.getClass}, locked = ${locked.toList}%, %, privateOK = ${selProto.privateOK}")
3598-
case _ =>
3599-
3600-
// try an extension method in scope
3601-
pt match {
3602-
case selProto @ SelectionProto(selName: TermName, mbrType, _, _) =>
3603-
3604-
def tryExtension(using Context): Tree =
3605-
findRef(selName, WildcardType, ExtensionMethod, EmptyFlags, tree.srcPos) match
3606-
case ref: TermRef =>
3607-
extMethodApply(untpd.ref(ref).withSpan(tree.span), tree, mbrType)
3608-
case _ =>
3609-
EmptyTree
3610-
3611-
try
3612-
val nestedCtx = ctx.fresh.setNewTyperState()
3613-
val app = tryExtension(using nestedCtx)
3614-
if !app.isEmpty && !nestedCtx.reporter.hasErrors then
3615-
nestedCtx.typerState.commit()
3616-
return ExtMethodApply(app)
3617-
else
3618-
for err <- nestedCtx.reporter.allErrors.take(1) do
3619-
rememberSearchFailure(tree,
3620-
SearchFailure(app.withType(FailedExtension(app, pt, err.msg))))
3621-
catch case ex: TypeError =>
3622-
rememberSearchFailure(tree,
3623-
SearchFailure(tree.withType(NestedFailure(ex.toMessage, pt))))
3624-
case _ =>
3625-
}
3626-
3627-
// try an implicit conversion
36283584
def recover(failure: SearchFailureType) =
36293585
if canDefineFurther(wtp) then readapt(tree)
36303586
else err.typeMismatch(tree, pt, failure)
36313587

3632-
if ctx.mode.is(Mode.ImplicitsEnabled) && tree.typeOpt.isValueType then
3633-
if pt.isRef(defn.AnyValClass, skipRefined = false)
3634-
|| pt.isRef(defn.ObjectClass, skipRefined = false)
3635-
then
3636-
report.error(em"the result of an implicit conversion must be more specific than $pt", tree.srcPos)
3637-
//println(i"try view $tree, ${tree.tpe}, $pt, ${inferView(tree, pt)}")
3588+
if pt.isInstanceOf[SelectionProto] then
3589+
tree // adaptations for selections are handled in typedSelect
3590+
else if ctx.mode.is(Mode.ImplicitsEnabled) && tree.tpe.isValueType then
3591+
checkConversionsSpecific(wtp, pt, tree.srcPos)
36383592
inferView(tree, pt) match {
36393593
case SearchSuccess(found: ExtMethodApply, _, _) =>
36403594
found // nothing to check or adapt for extension method applications

0 commit comments

Comments
 (0)