Skip to content

Commit 8510baf

Browse files
committed
Avoid unnecessary under-constrained 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 #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. Fixes #14333.
1 parent 0e4e5d5 commit 8510baf

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

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

+11-8
Original file line numberDiff line numberDiff line change
@@ -433,15 +433,18 @@ 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
437436
val resultApprox = resultTypeApprox(methType)
438-
if (!constrainResult(methRef.symbol, resultApprox, resultType))
439-
if (ctx.typerState.isCommittable)
440-
// defer the problem until after the application;
441-
// it might be healed by an implicit conversion
442-
()
443-
else
444-
fail(TypeMismatch(methType.resultType, resultType, None))
437+
val sym = methRef.symbol
438+
if ctx.typerState.isCommittable then
439+
// Here we call `resultType` only to accumulate constraints (even if
440+
// it fails, we might be able to heal the expression to conform to the
441+
// result type) so don't check for views since `viewExists` doesn't
442+
// have any side-effect and would only slow the compiler down (cf #14333).
443+
NoViewsAllowed.constrainResult(sym, resultApprox, resultType)
444+
else if !constrainResult(sym, resultApprox, resultType) then
445+
// Here we actually record that this alternative failed so that
446+
// overloading resolution might prune it.
447+
fail(TypeMismatch(methType.resultType, resultType, None))
445448

446449
// match all arguments with corresponding formal parameters
447450
matchArgs(orderedArgs, methType.paramInfos, 0)

0 commit comments

Comments
 (0)