Skip to content

Commit ec69880

Browse files
committed
Application#init: avoid unnecessary implicit searches
In some situations we only call `constrainResult` for its side-effects and ignore its result, but `constrainResult` calls `necessarilyCompatible` which will call `viewExists` as a last-try. Since `viewExists` doesn't have side-effects we might as well skip it, and it turns out that using `NoViewsAllowed.constrainResult` does exactly that. This leads to a significant speed-up (from ~8s to sub-second with a hot compiler) with the test case from scala#14333 (most likely this is because at the point where we call `constrainResult` we haven't accumulated any constraint from the arguments of the application, so implicit search is free to go on a wild goose chase). I also removed obsolete comments in this method.
1 parent 568c0f8 commit ec69880

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -433,19 +433,21 @@ trait Applications extends Compatibility {
433433

434434
protected def init(): Unit = methType match {
435435
case methType: MethodType =>
436-
// apply the result type constraint, unless method type is dependent
437-
val resultApprox = resultTypeApprox(methType)
438436
val obj: Compatibility = if (ctx.typerState.isCommittable) NoViewsAllowed else Applications.this
439437

440-
if (!obj.constrainResult(methRef.symbol, resultApprox, resultType))
441-
if (ctx.typerState.isCommittable)
442-
// defer the problem until after the application;
443-
// it might be healed by an implicit conversion
444-
()
445-
else
446-
fail(TypeMismatch(methType.resultType, resultType, None))
438+
val resultApprox = resultTypeApprox(methType)
439+
val sym = methRef.symbol
440+
if ctx.typerState.isCommittable then
441+
// Here we call `resultType` only to accumulate constraints (even if
442+
// it fails, we might be able to heal the expression to conform to the
443+
// result type) so don't check for views since `viewExists` doesn't
444+
// have any side-effect and would only slow the compiler done (cf #14333).
445+
NoViewsAllowed.constrainResult(sym, resultApprox, resultType)
446+
else if !constrainResult(sym, resultApprox, resultType) then
447+
// Here we actually record that this alternative failed so that
448+
// overloading resolution might prune it.
449+
fail(TypeMismatch(methType.resultType, resultType, None))
447450

448-
// match all arguments with corresponding formal parameters
449451
matchArgs(orderedArgs, methType.paramInfos, 0)
450452
case _ =>
451453
if (methType.isError) ok = false

0 commit comments

Comments
 (0)