@@ -37,6 +37,7 @@ import scala.io.Codec
3737import Run .Progress
3838import scala .compiletime .uninitialized
3939import dotty .tools .dotc .transform .MegaPhase
40+ import dotty .tools .dotc .transform .Pickler .AsyncTastyHolder
4041
4142/** A compiler run. Exports various methods to compile source files */
4243class Run (comp : Compiler , ictx : Context ) extends ImplicitRunInfo with ConstraintRunInfo {
@@ -130,7 +131,10 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
130131 myUnits = us
131132
132133 var suspendedUnits : mutable.ListBuffer [CompilationUnit ] = mutable.ListBuffer ()
133- var suspendedHints : mutable.Map [CompilationUnit , String ] = mutable.HashMap ()
134+ var suspendedHints : mutable.Map [CompilationUnit , (String , Boolean )] = mutable.HashMap ()
135+
136+ /** Were any units suspended in the typer phase? if so then pipeline tasty can not complete. */
137+ var suspendedAtTyperPhase : Boolean = false
134138
135139 def checkSuspendedUnits (newUnits : List [CompilationUnit ])(using Context ): Unit =
136140 if newUnits.isEmpty && suspendedUnits.nonEmpty && ! ctx.reporter.errorsReported then
@@ -231,6 +235,22 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
231235 if ! progress.isCancelled() then
232236 progress.tickSubphase()
233237
238+ /** if true, then we are done writing pipelined TASTy files (i.e. finished in a previous run.) */
239+ private var myAsyncTastyWritten = false
240+
241+ private var _asyncTasty : Option [AsyncTastyHolder ] = None
242+
243+ /** populated when this run needs to write pipeline TASTy files. */
244+ def asyncTasty : Option [AsyncTastyHolder ] = _asyncTasty
245+
246+ private def initializeAsyncTasty ()(using Context ): () => Unit =
247+ // should we provide a custom ExecutionContext?
248+ // currently it is just used to call the `apiPhaseCompleted` and `dependencyPhaseCompleted` callbacks in Zinc
249+ import scala .concurrent .ExecutionContext .Implicits .global
250+ val async = AsyncTastyHolder .init
251+ _asyncTasty = Some (async)
252+ () => async.cancel()
253+
234254 /** Will be set to true if any of the compiled compilation units contains
235255 * a pureFunctions language import.
236256 */
@@ -348,7 +368,14 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
348368 runCtx.setProperty(CyclicReference .Trace , new CyclicReference .Trace ())
349369 runCtx.withProgressCallback: cb =>
350370 _progress = Progress (cb, this , fusedPhases.map(_.traversals).sum)
371+ val cancelAsyncTasty : () => Unit =
372+ if ! myAsyncTastyWritten && Phases .picklerPhase.exists && ! ctx.settings.YearlyTastyOutput .isDefault then
373+ initializeAsyncTasty()
374+ else () => {}
375+
351376 runPhases(allPhases = fusedPhases)(using runCtx)
377+ cancelAsyncTasty()
378+
352379 ctx.reporter.finalizeReporting()
353380 if (! ctx.reporter.hasErrors)
354381 Rewrites .writeBack()
@@ -365,9 +392,12 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
365392 /** Is this run started via a compilingSuspended? */
366393 def isCompilingSuspended : Boolean = myCompilingSuspended
367394
368- /** Compile units `us` which were suspended in a previous run */
369- def compileSuspendedUnits (us : List [CompilationUnit ]): Unit =
395+ /** Compile units `us` which were suspended in a previous run,
396+ * also signal if all necessary async tasty files were written in a previous run.
397+ */
398+ def compileSuspendedUnits (us : List [CompilationUnit ], asyncTastyWritten : Boolean ): Unit =
370399 myCompilingSuspended = true
400+ myAsyncTastyWritten = asyncTastyWritten
371401 for unit <- us do unit.suspended = false
372402 compileUnits(us)
373403
0 commit comments