Skip to content

Commit 02ff67a

Browse files
committed
Avoid Context#clone
1 parent c7e70d0 commit 02ff67a

File tree

1 file changed

+54
-47
lines changed

1 file changed

+54
-47
lines changed

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,20 @@ object Contexts {
6868
* of all class fields of type context; allow them only in whitelisted
6969
* classes (which should be short-lived).
7070
*/
71-
abstract class Context extends Periods
72-
with Substituters
73-
with TypeOps
74-
with Phases
75-
with Printers
76-
with Symbols
77-
with SymDenotations
78-
with Reporting
79-
with NamerContextOps
80-
with Plugins
81-
with Cloneable { thiscontext =>
82-
implicit def ctx: Context = this
71+
abstract class Context(val base: ContextBase)
72+
extends Periods
73+
with Substituters
74+
with TypeOps
75+
with Phases
76+
with Printers
77+
with Symbols
78+
with SymDenotations
79+
with Reporting
80+
with NamerContextOps
81+
with Plugins
82+
with Cloneable { thiscontext =>
8383

84-
/** The context base at the root */
85-
val base: ContextBase
84+
implicit def ctx: Context = this
8685

8786
/** All outer contexts, ending in `base.initialCtx` and then `NoContext` */
8887
def outersIterator: Iterator[Context] = new Iterator[Context] {
@@ -94,83 +93,85 @@ object Contexts {
9493
/** The outer context */
9594
private[this] var _outer: Context = _
9695
protected def outer_=(outer: Context): Unit = _outer = outer
97-
def outer: Context = _outer
96+
final def outer: Context = _outer
9897

9998
/** The current context */
10099
private[this] var _period: Period = _
101100
protected def period_=(period: Period): Unit = {
102101
assert(period.firstPhaseId == period.lastPhaseId, period)
103102
_period = period
104103
}
105-
def period: Period = _period
104+
final def period: Period = _period
106105

107106
/** The scope nesting level */
108107
private[this] var _mode: Mode = _
109108
protected def mode_=(mode: Mode): Unit = _mode = mode
110-
def mode: Mode = _mode
109+
final def mode: Mode = _mode
111110

112111
/** The current owner symbol */
113112
private[this] var _owner: Symbol = _
114113
protected def owner_=(owner: Symbol): Unit = _owner = owner
115-
def owner: Symbol = _owner
114+
final def owner: Symbol = _owner
116115

117116
/** The current tree */
118117
private[this] var _tree: Tree[_ >: Untyped]= _
119118
protected def tree_=(tree: Tree[_ >: Untyped]): Unit = _tree = tree
120-
def tree: Tree[_ >: Untyped] = _tree
119+
final def tree: Tree[_ >: Untyped] = _tree
121120

122121
/** The current scope */
123122
private[this] var _scope: Scope = _
124123
protected def scope_=(scope: Scope): Unit = _scope = scope
125-
def scope: Scope = _scope
124+
final def scope: Scope = _scope
126125

127126
/** The current type comparer */
128127
private[this] var _typerState: TyperState = _
129128
protected def typerState_=(typerState: TyperState): Unit = _typerState = typerState
130-
def typerState: TyperState = _typerState
129+
final def typerState: TyperState = _typerState
131130

132131
/** The current type assigner or typer */
133132
private[this] var _typeAssigner: TypeAssigner = _
134133
protected def typeAssigner_=(typeAssigner: TypeAssigner): Unit = _typeAssigner = typeAssigner
135-
def typeAssigner: TypeAssigner = _typeAssigner
134+
final def typeAssigner: TypeAssigner = _typeAssigner
136135

137136
/** The currently active import info */
138137
private[this] var _importInfo: ImportInfo = _
139138
protected def importInfo_=(importInfo: ImportInfo): Unit = _importInfo = importInfo
140-
def importInfo: ImportInfo = _importInfo
139+
final def importInfo: ImportInfo = _importInfo
141140

142141
/** The current bounds in force for type parameters appearing in a GADT */
143142
private[this] var _gadt: GADTMap = _
144143
protected def gadt_=(gadt: GADTMap): Unit = _gadt = gadt
145-
def gadt: GADTMap = _gadt
144+
final def gadt: GADTMap = _gadt
146145

147146
/** The history of implicit searches that are currently active */
148147
private[this] var _searchHistory: SearchHistory = null
149148
protected def searchHistory_= (searchHistory: SearchHistory): Unit = _searchHistory = searchHistory
150-
def searchHistory: SearchHistory = _searchHistory
149+
final def searchHistory: SearchHistory = _searchHistory
151150

152151
/** The current type comparer. This ones updates itself automatically for
153152
* each new context.
154153
*/
155-
private[this] var _typeComparer: TypeComparer = _
156-
protected def typeComparer_=(typeComparer: TypeComparer): Unit = _typeComparer = typeComparer
157-
def typeComparer: TypeComparer = {
158-
if (_typeComparer.ctx ne this)
159-
_typeComparer = _typeComparer.copyIn(this)
154+
private[this] var _typeComparer: TypeComparer = null
155+
protected def typeComparer_=(typeComparer: TypeComparer): Unit = {
156+
assert(typeComparer.ctx eq this)
157+
_typeComparer = typeComparer
158+
}
159+
final def typeComparer: TypeComparer = {
160+
if (_typeComparer == null) _typeComparer = outer.typeComparer.copyIn(this)
160161
_typeComparer
161162
}
162163

163164
/** The current source file */
164165
private[this] var _source: SourceFile = _
165166
protected def source_=(source: SourceFile): Unit = _source = source
166-
def source: SourceFile = _source
167+
final def source: SourceFile = _source
167168

168169
/** A map in which more contextual properties can be stored
169170
* Typically used for attributes that are read and written only in special situations.
170171
*/
171172
private[this] var _moreProperties: Map[Key[Any], Any] = _
172173
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]): Unit = _moreProperties = moreProperties
173-
def moreProperties: Map[Key[Any], Any] = _moreProperties
174+
final def moreProperties: Map[Key[Any], Any] = _moreProperties
174175

175176
def property[T](key: Key[T]): Option[T] =
176177
moreProperties.get(key).asInstanceOf[Option[T]]
@@ -182,7 +183,7 @@ object Contexts {
182183
*/
183184
private var _store: Store = _
184185
protected def store_=(store: Store): Unit = _store = store
185-
def store: Store = _store
186+
final def store: Store = _store
186187

187188
/** The compiler callback implementation, or null if no callback will be called. */
188189
def compilerCallback: CompilerCallback = store(compilerCallbackLoc)
@@ -258,7 +259,7 @@ object Contexts {
258259
* phasedCtxs is array that uses phaseId's as indexes,
259260
* contexts are created only on request and cached in this array
260261
*/
261-
private[this] var phasedCtx: Context = _
262+
private[this] var phasedCtx: Context = this
262263
private[this] var phasedCtxs: Array[Context] = _
263264

264265
/** This context at given phase.
@@ -422,20 +423,27 @@ object Contexts {
422423
base.settings.color.value == "always"
423424

424425
protected def init(outer: Context): this.type = {
425-
this.outer = outer
426-
this.implicitsCache = null
427-
this.phasedCtx = this
428-
this.phasedCtxs = null
429-
this.sourceCtx = null
430-
// See comment related to `creationTrace` in this file
431-
// setCreationTrace()
426+
_outer = outer
427+
_period = outer.period
428+
_mode = outer.mode
429+
_owner = outer.owner
430+
_tree = outer.tree
431+
_scope = outer.scope
432+
_typerState = outer.typerState
433+
_typeAssigner = outer.typeAssigner
434+
_importInfo = outer.importInfo
435+
_gadt = outer.gadt
436+
_searchHistory = outer.searchHistory
437+
_source = outer.source
438+
_moreProperties = outer.moreProperties
439+
_store = outer.store
432440
this
433441
}
434442

435443
/** A fresh clone of this context. */
436444
def fresh: FreshContext = {
437445
util.Stats.record("Context.fresh")
438-
clone.asInstanceOf[FreshContext].init(this)
446+
new FreshContext(base).init(this)
439447
}
440448

441449
final def withOwner(owner: Symbol): Context =
@@ -511,7 +519,7 @@ object Contexts {
511519
/** A fresh context allows selective modification
512520
* of its attributes using the with... methods.
513521
*/
514-
abstract class FreshContext extends Context {
522+
class FreshContext(base: ContextBase) extends Context(base) {
515523
def setPeriod(period: Period): this.type = { this.period = period; this }
516524
def setMode(mode: Mode): this.type = { this.mode = mode; this }
517525
def setOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
@@ -595,7 +603,7 @@ object Contexts {
595603
/** A class defining the initial context with given context base
596604
* and set of possible settings.
597605
*/
598-
private class InitialContext(val base: ContextBase, settingsGroup: SettingGroup) extends FreshContext {
606+
private class InitialContext(base: ContextBase, settingsGroup: SettingGroup) extends FreshContext(base) {
599607
outer = NoContext
600608
period = InitialPeriod
601609
mode = Mode.None
@@ -611,9 +619,8 @@ object Contexts {
611619
gadt = EmptyGADTMap
612620
}
613621

614-
@sharable object NoContext extends Context {
615-
override def source = NoSource
616-
val base: ContextBase = null
622+
@sharable object NoContext extends Context(null) {
623+
source = NoSource
617624
override val implicits: ContextualImplicits = new ContextualImplicits(Nil, null)(this)
618625
}
619626

0 commit comments

Comments
 (0)