Skip to content

Commit 1cb4279

Browse files
committed
Have a per-run time budget for import suggestions
Keep a budget of import suggestions per run. The first timeout is 10sec. Each successive timeout is the previous timeout reduced by the search time of the previous suggestion search, but at least half the previous timeout.
1 parent 3dfba6d commit 1cb4279

File tree

3 files changed

+156
-5
lines changed

3 files changed

+156
-5
lines changed

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

+17
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,23 @@ trait ImplicitRunInfo:
481481

482482
private val EmptyTermRefSet = new TermRefSet(using NoContext)
483483

484+
/** Global timeout to stop looking for further implicit suggestions, in ms.
485+
* This is for the first import suggestion; subsequent suggestions
486+
* get smaller timeouts.
487+
*/
488+
private inline val suggestFirstImplicitsTimeOut = 10000
489+
490+
private var importSuggestionBudget: Long = suggestFirstImplicitsTimeOut
491+
492+
/** The current timeout for import suggestions */
493+
def nextImportSuggestionTimeout() = importSuggestionBudget
494+
495+
/** Reduce the import suggestion timeout by `ms`, but make sure that
496+
* the new timeout is at least half the old one.
497+
*/
498+
def reduceImportSuggestionTimeout(ms: Long) =
499+
importSuggestionBudget = (importSuggestionBudget - ms) max (importSuggestionBudget / 2)
500+
484501
private def isExcluded(sym: Symbol) =
485502
if migrateTo3 then false else sym.is(Package) || sym.isPackageObject
486503

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ trait ImportSuggestions:
2727
/** Timeout to test a single implicit value as a suggestion, in ms */
2828
private inline val testOneImplicitTimeOut = 500
2929

30-
/** Global timeout to stop looking for further implicit suggestions, in ms */
31-
private inline val suggestImplicitTimeOut = 10000
32-
3330
/** A list of TermRefs referring to the roots where suggestions for
3431
* imports of givens or extension methods that might fix a type error
3532
* are searched.
@@ -145,7 +142,11 @@ trait ImportSuggestions:
145142
*/
146143
private def importSuggestions(pt: Type)(using Context): (List[TermRef], List[TermRef]) =
147144
val timer = new Timer()
148-
val deadLine = System.currentTimeMillis() + suggestImplicitTimeOut
145+
val allotted = ctx.run.nextImportSuggestionTimeout()
146+
if allotted <= 1 then return (Nil, Nil)
147+
implicits.println(i"looking for import suggestions, timeout = ${allotted}ms")
148+
val start = System.currentTimeMillis()
149+
val deadLine = start + allotted
149150

150151
// Candidates that are already available without explicit import because they
151152
// are already provided by the context (imported or inherited) or because they
@@ -249,7 +250,9 @@ trait ImportSuggestions:
249250
println("caught exception when searching for suggestions")
250251
ex.printStackTrace()
251252
(Nil, Nil)
252-
finally timer.cancel()
253+
finally
254+
timer.cancel()
255+
ctx.run.reduceImportSuggestionTimeout(System.currentTimeMillis() - start)
253256
end importSuggestions
254257

255258
/** The `ref` parts of this list of pairs, discarding subsequent elements that

0 commit comments

Comments
 (0)