Skip to content

Commit 3138600

Browse files
committed
Supress safe initialization warning in Run class
Due to the `this` pointer being passed to `start.setRun` in a function called during initialization, the initialization checker cannot prove that `this` is fully initialized. We would get the following error: ``` [error] -- Error: /*******/dotty/compiler/src/dotty/tools/dotc/Run.scala:84:17 [error] 84 | start.setRun(this) [error] | ^^^^ [error] |Cannot prove that the value is fully initialized. Only initialized values may be used as arguments. Calling trace: [error] | -> val run = new Run(this, initCtx) { [ ReplCompiler.scala:42 ] [error] | -> class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with ConstraintRunInfo {iler-b[ Run.scala:38 ] [error] | -> private var myCtx = rootContext(using ictx) [ Run.scala:89 ] [error] | -> val rootCtx = super.rootContext.fresh [ ReplCompiler.scala:62 ] ``` The call to `start.setRun` stores the reference to `this` in a store without accessing any of its fields. The instance of `Run` referrred to by `this` will be fully initialized immediately after that function call. Thus, we are able to safely mark `this` as `@unchecked` without worrying about uninitialized members of the `Run` instance being accessed. Review by @liufengyun
1 parent ddac928 commit 3138600

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -57,41 +57,8 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
5757
*/
5858
@volatile var isCancelled = false
5959

60-
/** Produces the following contexts, from outermost to innermost
61-
*
62-
* bootStrap: A context with next available runId and a scope consisting of
63-
* the RootPackage _root_
64-
* start A context with RootClass as owner and the necessary initializations
65-
* for type checking.
66-
* imports For each element of RootImports, an import context
67-
*/
68-
protected def rootContext(using Context): Context = {
69-
ctx.initialize()
70-
ctx.base.setPhasePlan(comp.phases)
71-
val rootScope = new MutableScope(0)
72-
val bootstrap = ctx.fresh
73-
.setPeriod(Period(comp.nextRunId, FirstPhaseId))
74-
.setScope(rootScope)
75-
rootScope.enter(ctx.definitions.RootPackage)(using bootstrap)
76-
var start = bootstrap.fresh
77-
.setOwner(defn.RootClass)
78-
.setTyper(new Typer)
79-
.addMode(Mode.ImplicitsEnabled)
80-
.setTyperState(ctx.typerState.fresh(ctx.reporter))
81-
if ctx.settings.YexplicitNulls.value && !Feature.enabledBySetting(nme.unsafeNulls) then
82-
start = start.addMode(Mode.SafeNulls)
83-
ctx.initialize()(using start) // re-initialize the base context with start
84-
start.setRun(this)
85-
}
86-
8760
private var compiling = false
8861

89-
private var myCtx = rootContext(using ictx)
90-
91-
/** The context created for this run */
92-
given runContext[Dummy_so_its_a_def]: Context = myCtx
93-
assert(runContext.runId <= Periods.MaxPossibleRunId)
94-
9562
private var myUnits: List[CompilationUnit] = _
9663
private var myUnitsCached: List[CompilationUnit] = _
9764
private var myFiles: Set[AbstractFile] = _
@@ -369,4 +336,40 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
369336
myUnits = null
370337
myUnitsCached = null
371338
}
339+
340+
/** Produces the following contexts, from outermost to innermost
341+
*
342+
* bootStrap: A context with next available runId and a scope consisting of
343+
* the RootPackage _root_
344+
* start A context with RootClass as owner and the necessary initializations
345+
* for type checking.
346+
* imports For each element of RootImports, an import context
347+
*/
348+
protected def rootContext(using Context): Context = {
349+
ctx.initialize()
350+
ctx.base.setPhasePlan(comp.phases)
351+
val rootScope = new MutableScope(0)
352+
val bootstrap = ctx.fresh
353+
.setPeriod(Period(comp.nextRunId, FirstPhaseId))
354+
.setScope(rootScope)
355+
rootScope.enter(ctx.definitions.RootPackage)(using bootstrap)
356+
var start = bootstrap.fresh
357+
.setOwner(defn.RootClass)
358+
.setTyper(new Typer)
359+
.addMode(Mode.ImplicitsEnabled)
360+
.setTyperState(ctx.typerState.fresh(ctx.reporter))
361+
if ctx.settings.YexplicitNulls.value && !Feature.enabledBySetting(nme.unsafeNulls) then
362+
start = start.addMode(Mode.SafeNulls)
363+
ctx.initialize()(using start) // re-initialize the base context with start
364+
365+
// `this` must be unchecked for safe initialization because by being passed to setRun during
366+
// initialization, it is not yet considered fully initialized by the initialization checker
367+
start.setRun(this: @unchecked)
368+
}
369+
370+
private var myCtx = rootContext(using ictx)
371+
372+
/** The context created for this run */
373+
given runContext[Dummy_so_its_a_def]: Context = myCtx
374+
assert(runContext.runId <= Periods.MaxPossibleRunId)
372375
}

0 commit comments

Comments
 (0)