From ce372c540c5a879db5bf9792b3448ca932f503e5 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 26 Mar 2014 16:38:59 +0100 Subject: [PATCH 1/6] Reworked phases. Aims 1) next/prev should be context-independent. Phase now stores its ContextBase in a field. 2) More robust handling of phaseNamed and the phase properties erasedTypes, flattened, refchecked, etc. These were previously dependent on when the first call to any of these methods was made, which led to a data race. There is now an init method in phases which centralizes all necessary intialization. It is checked that a phase is initialized only once. --- src/dotty/tools/dotc/core/Phases.scala | 108 ++++++++++++++++--------- 1 file changed, 68 insertions(+), 40 deletions(-) diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index c49d314bc376..7ae7b6ad3bca 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -45,8 +45,6 @@ object Phases { // drop NoPhase at beginning def allPhases = squashedPhases.tail - - object NoPhase extends Phase { override def exists = false def name = "" @@ -68,26 +66,23 @@ object Phases { override def lastPhaseId(implicit ctx: Context) = id } - def phaseNamed(name: String) = - phases.find(_.name == name).getOrElse(NoPhase) - /** Use the following phases in the order they are given. * The list should never contain NoPhase. * if squashing is enabled, phases in same subgroup will be squashed to single phase. */ - def usePhases(phases: List[List[Phase]], squash: Boolean = true) = { - this.phases = (NoPhase :: phases.flatten ::: new TerminalPhase :: Nil).toArray - this.nextDenotTransformerId = new Array[Int](this.phases.length) - this.denotTransformers = new Array[DenotTransformer](this.phases.length) + def usePhases(phasess: List[List[Phase]], squash: Boolean = false) = { + phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray + nextDenotTransformerId = new Array[Int](phases.length) + denotTransformers = new Array[DenotTransformer](phases.length) var i = 0 - while (i < this.phases.length) { - this.phases(i)._id = i + while (i < phases.length) { + phases(i).init(this, i) i += 1 } var lastTransformerId = i while (i > 0) { i -= 1 - this.phases(i) match { + phases(i) match { case transformer: DenotTransformer => lastTransformerId = i denotTransformers(i) = transformer @@ -100,11 +95,11 @@ object Phases { val squashedPhases = ListBuffer[Phase]() var postTyperEmmited = false var i = 0 - while (i < phases.length) { - if (phases(i).length > 1) { - assert(phases(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed") + while (i < phasess.length) { + if (phasess(i).length > 1) { + assert(phasess(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed") - val transforms = phases(i).asInstanceOf[List[TreeTransform]] + val transforms = phasess(i).asInstanceOf[List[TreeTransform]] val block = if (!postTyperEmmited) { postTyperEmmited = true @@ -117,8 +112,8 @@ object Phases { override protected def transformations: Array[TreeTransform] = transforms.toArray } squashedPhases += block - block._id = phases(i).head.id - } else squashedPhases += phases(i).head + block.init(this, phasess(i).head.id) + } else squashedPhases += phasess(i).head i += 1 } this.squashedPhases = (NoPhase::squashedPhases.toList :::new TerminalPhase :: Nil).toArray @@ -126,22 +121,41 @@ object Phases { this.squashedPhases = this.phases } - config.println(s"Phases = ${this.phases.deep}") - config.println(s"squashedPhases = ${this.squashedPhases.deep}") + config.println(s"Phases = ${phases.deep}") + config.println(s"squashedPhases = ${squashedPhases.deep}") config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.deep}") } - final val typerName = "typer" - final val refchecksName = "refchecks" - final val erasureName = "erasure" - final val flattenName = "flatten" + def phaseNamed(name: String) = phases.find(_.name == name).getOrElse(NoPhase) - lazy val typerPhase = phaseNamed(typerName) - lazy val refchecksPhase = phaseNamed(refchecksName) - lazy val erasurePhase = phaseNamed(erasureName) - lazy val flattenPhase = phaseNamed(flattenName) + /** A cache to compute the phase with given name, which + * stores the phase as soon as phaseNamed returns something + * different from NoPhase. + */ + private class PhaseCache(name: String) { + private var myPhase: Phase = NoPhase + def phase = { + if (myPhase eq NoPhase) myPhase = phaseNamed(name) + myPhase + } + } + + private val typerCache = new PhaseCache(typerName) + private val refChecksCache = new PhaseCache(refChecksName) + private val erasureCache = new PhaseCache(erasureName) + private val flattenCache = new PhaseCache(flattenName) + + def typerPhase = typerCache.phase + def refchecksPhase = refChecksCache.phase + def erasurePhase = erasureCache.phase + def flattenPhase = flattenCache.phase } + final val typerName = "typer" + final val refChecksName = "refchecks" + final val erasureName = "erasure" + final val flattenName = "flatten" + abstract class Phase extends DotClass { def name: String @@ -157,32 +171,46 @@ object Phases { def exists: Boolean = true - private[Phases] var _id = -1 + private var myId: PhaseId = -1 + private var myBase: ContextBase = null + private var myErasedTypes = false + private var myFlatClasses = false + private var myRefChecked = false /** The sequence position of this phase in the given context where 0 * is reserved for NoPhase and the first real phase is at position 1. * -1 if the phase is not installed in the context. */ - def id = _id + def id = myId + + final def erasedTypes = myErasedTypes + final def flatClasses = myFlatClasses + final def refChecked = myRefChecked + + protected[Phases] def init(base: ContextBase, id: Int): Unit = { + if (id >= FirstPhaseId) + assert(myId == -1, s"phase $this has already been used once; cannot be reused") + myBase = base + myId = id + myErasedTypes = prev.name == erasureName || prev.erasedTypes + myFlatClasses = prev.name == flattenName || prev.flatClasses + myRefChecked = prev.name == refChecksName || prev.refChecked + } final def <=(that: Phase)(implicit ctx: Context) = exists && id <= that.id - final def prev(implicit ctx: Context): Phase = - if (id > FirstPhaseId) ctx.phases(id - 1) else ctx.NoPhase + final def prev: Phase = + if (id > FirstPhaseId) myBase.phases(id - 1) else myBase.NoPhase - final def next(implicit ctx: Context): Phase = - if (hasNext) ctx.phases(id + 1) else ctx.NoPhase + final def next: Phase = + if (hasNext) myBase.phases(id + 1) else myBase.NoPhase - final def hasNext(implicit ctx: Context) = id + 1 < ctx.phases.length + final def hasNext = id >= FirstPhaseId && id + 1 < myBase.phases.length - final def iterator(implicit ctx: Context) = + final def iterator = Iterator.iterate(this)(_.next) takeWhile (_.hasNext) - final def erasedTypes(implicit ctx: Context): Boolean = ctx.erasurePhase <= this - final def flatClasses(implicit ctx: Context): Boolean = ctx.flattenPhase <= this - final def refChecked(implicit ctx: Context): Boolean = ctx.refchecksPhase <= this - override def toString = name } } \ No newline at end of file From 0e2deaa32e57661743b2cf243833cafee5388b70 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 26 Mar 2014 16:40:05 +0100 Subject: [PATCH 2/6] Changes to how we compute type parameters Aim: Avoid expensive scanning of definitions in denotations other than the initial one. Technique: 1. If phase is erased, type params is Nil (except for Array class) 2. Otherwise, type params is the same as it was in initial phase. --- src/dotty/tools/dotc/core/SymDenotations.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 362738caf3e8..248cf3de3d54 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -805,8 +805,12 @@ object SymDenotations { /** The type parameters of this class */ override final def typeParams(implicit ctx: Context): List[TypeSymbol] = { - def computeTypeParams = decls.filter(sym => - (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]] + def computeTypeParams = { + if (ctx.phase.erasedTypes && (this ne defn.ArrayClass)) Nil + else if (this ne initial) initial.asSymDenotation.typeParams + else decls.filter(sym => + (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]] + } if (myTypeParams == null) myTypeParams = computeTypeParams myTypeParams } From 29c876a40adaae17d4f47cee906243bda9d8e606 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 26 Mar 2014 16:59:51 +0100 Subject: [PATCH 3/6] Fix context.withPhase Previous version was wrong because every context is a fresh context at runtime, so the overriding version would always be executed, which means that withPhase becomes a side-effecting operation! --- src/dotty/tools/dotc/core/Contexts.scala | 10 +++++----- src/dotty/tools/dotc/core/Periods.scala | 2 +- src/dotty/tools/dotc/core/Phases.scala | 2 +- src/dotty/tools/dotc/core/Types.scala | 2 +- src/dotty/tools/dotc/transform/TreeTransform.scala | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 9fbba9a0fc90..da684ea9cfd3 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -280,9 +280,9 @@ object Contexts { final def withMode(mode: Mode): Context = if (mode != this.mode) fresh.withNewMode(mode) else this - def withPhase(phase: PhaseId): Context = - if (this.phaseId == phaseId) this else fresh.withPhase(phase) - def withPhase(phase: Phase): Context = + final def withPhase(phase: PhaseId): Context = + if (this.phaseId == phaseId) this else fresh.withNewPhase(phase) + final def withPhase(phase: Phase): Context = withPhase(phase.id) final def addMode(mode: Mode): Context = withMode(this.mode | mode) @@ -329,8 +329,8 @@ object Contexts { def withProperty(prop: (String, Any)): this.type = withMoreProperties(moreProperties + prop) - override def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid)) - override def withPhase(phase: Phase): this.type = withPhase(phase.id) + def withNewPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid)) + def withNewPhase(phase: Phase): this.type = withNewPhase(phase.id) def withSetting[T](setting: Setting[T], value: T): this.type = withSettings(setting.updateIn(sstate, value)) diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala index 61f395c7d87a..6e1522e269d0 100644 --- a/src/dotty/tools/dotc/core/Periods.scala +++ b/src/dotty/tools/dotc/core/Periods.scala @@ -23,7 +23,7 @@ abstract class Periods extends DotClass { self: Context => /** Execute `op` at given phase id */ def atPhase[T](pid: PhaseId)(op: Context => T): T = - op(ctx.fresh.withPhase(pid)) + op(ctx.withPhase(pid)) /** The period containing the current period where denotations do not change. * We compute this by taking as first phase the first phase less or equal to diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 7ae7b6ad3bca..ee993b8905bd 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -163,7 +163,7 @@ object Phases { def run(implicit ctx: Context): Unit def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = - for (unit <- units) run(ctx.fresh.withPhase(this).withCompilationUnit(unit)) + for (unit <- units) run(ctx.fresh.withNewPhase(this).withCompilationUnit(unit)) def description: String = name diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 7cd66f5ddd5f..501f01a745e8 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1066,7 +1066,7 @@ object Types { if (d.exists || ctx.phaseId == FirstPhaseId) d else {// name has changed; try load in earlier phase and make current - val d = denot(ctx.fresh.withPhase(ctx.phaseId - 1)).current + val d = denot(ctx.withPhase(ctx.phaseId - 1)).current if (d.exists) d else throw new Error(s"failure to reload $this") } diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index 2fa2f3abb9f0..10857da5afc9 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -484,7 +484,7 @@ object TreeTransforms { def transform(t: Tree)(implicit ctx: Context): Tree = { val initialTransformations = transformations - val contexts = initialTransformations.map(tr => ctx.fresh.withPhase(tr).ctx) + val contexts = initialTransformations.map(tr => ctx.withPhase(tr).ctx) val info = new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations), this, contexts) initialTransformations.zipWithIndex.foreach{ case (transform, id) => From a6419fbd80bb63413de671af331ae35da4fa4e1b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 26 Mar 2014 17:02:49 +0100 Subject: [PATCH 4/6] Fix Denotations#current The logic for dealing with periods in denotation histories did not correctly take into account the case where the current validity period of a denotation ends some phases before the next type transformer starts. And there was an off-by-one error in startPid. And Types#computeDenot erroneously tried to reload denotations even the run did not change. --- src/dotty/tools/dotc/core/Denotations.scala | 53 +++++++++++++-------- src/dotty/tools/dotc/core/Types.scala | 2 +- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 35f6bd56fbf5..1e3dec255bb2 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -19,6 +19,7 @@ import printing.Printer import io.AbstractFile import config.Config import util.common._ +import collection.mutable.ListBuffer import Decorators.SymbolIteratorDecorator /** Denotations represent the meaning of symbols and named types. @@ -459,7 +460,7 @@ object Denotations { * 2) the union of all validity periods is a contiguous * interval. */ - var nextInRun: SingleDenotation = this + private var nextInRun: SingleDenotation = this /** The version of this SingleDenotation that was valid in the first phase * of this run. @@ -470,6 +471,17 @@ object Denotations { current } + def history: List[SingleDenotation] = { + val b = new ListBuffer[SingleDenotation] + var current = initial + do { + b += (current) + current = current.nextInRun + } + while (current ne initial) + b.toList + } + /** Move validity period of this denotation to a new run. Throw a StaleSymbol error * if denotation is no longer valid. */ @@ -518,27 +530,30 @@ object Denotations { cur = next cur } else { + //println(s"might need new denot for $cur, valid for ${cur.validFor} at $currentPeriod") // not found, cur points to highest existing variant - var startPid = cur.validFor.lastPhaseId + 1 - val nextTranformerId = ctx.nextDenotTransformerId(startPid) - val transformer = ctx.denotTransformers(nextTranformerId) - //println(s"transforming with $transformer") - if (currentPeriod.lastPhaseId > transformer.id) - next = transformer.transform(cur)(ctx.withPhase(startPid)).syncWithParents - if (next eq cur) - startPid = cur.validFor.firstPhaseId + val nextTransformerId = ctx.nextDenotTransformerId(cur.validFor.lastPhaseId) + if (currentPeriod.lastPhaseId <= nextTransformerId) + cur.validFor = Period(currentPeriod.runId, cur.validFor.firstPhaseId, nextTransformerId) else { - next match { - case next: ClassDenotation => next.resetFlag(Frozen) - case _ => + var startPid = nextTransformerId + 1 + val transformer = ctx.denotTransformers(nextTransformerId) + //println(s"transforming $this with $transformer") + next = transformer.transform(cur)(ctx.withPhase(transformer)).syncWithParents + if (next eq cur) + startPid = cur.validFor.firstPhaseId + else { + next match { + case next: ClassDenotation => next.resetFlag(Frozen) + case _ => + } + next.nextInRun = cur.nextInRun + cur.nextInRun = next + cur = next } - next.nextInRun = cur.nextInRun - cur.nextInRun = next - cur = next + cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId) + //println(s"new denot: $cur, valid for ${cur.validFor}") } - cur.validFor = Period( - currentPeriod.runId, startPid, transformer.lastPhaseId) - //println(s"new denot: $cur, valid for ${cur.validFor}") cur.current // multiple transformations could be required } } else { @@ -562,7 +577,7 @@ object Denotations { case denot: SymDenotation => s"in ${denot.owner}" case _ => "" } - def msg = s"stale symbol; $this#${symbol.id}$ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.period.runId}" + def msg = s"stale symbol; $this#${symbol.id} $ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.runId}" throw new StaleSymbol(msg) } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 501f01a745e8..ce481759bd4d 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1028,7 +1028,7 @@ object Types { val sym = lastSymbol if (sym == null) loadDenot else denotOfSym(sym) case d: SymDenotation => - if (ctx.stillValid(d)) d.current + if (d.validFor.runId == ctx.runId || ctx.stillValid(d)) d.current else { val newd = loadDenot if (newd.exists) newd else d.staleSymbolError From ad81775080f45f918027683c8022d82b057d5706 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Thu, 27 Mar 2014 12:45:31 +0100 Subject: [PATCH 5/6] Rename stillValid to isValidInRun, add quickpath to it --- src/dotty/tools/dotc/core/Denotations.scala | 2 +- src/dotty/tools/dotc/core/SymDenotations.scala | 11 ++++++----- src/dotty/tools/dotc/core/Types.scala | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 1e3dec255bb2..a5efee55a487 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -486,7 +486,7 @@ object Denotations { * if denotation is no longer valid. */ private def bringForward()(implicit ctx: Context): SingleDenotation = this match { - case denot: SymDenotation if ctx.stillValid(denot) => + case denot: SymDenotation if ctx.isValidInRun(denot) => if (denot.exists) assert(ctx.runId > validFor.runId, s"denotation $denot invalid in run ${ctx.runId}. ValidFor: $validFor") var d: SingleDenotation = denot do { diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 248cf3de3d54..5c11b266eb8e 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -38,17 +38,18 @@ trait SymDenotations { this: Context => result } - def stillValid(denot: SymDenotation): Boolean = - if (denot is ValidForever) true + def isValidInRun(denot: SymDenotation): Boolean = + if(denot.validFor.runId == this.runId) true + else if (denot is ValidForever) true else try { val owner = denot.owner.denot def isSelfSym = owner.infoOrCompleter match { case ClassInfo(_, _, _, _, selfInfo) => selfInfo == denot.symbol case _ => false } - stillValid(owner) && owner.isClass && ( - (owner.decls.lookupAll(denot.name) contains denot.symbol) - || isSelfSym + isValidInRun(owner) && owner.isClass && ( + (owner.decls.lookupAll(denot.name) contains denot.symbol) + || isSelfSym ) } catch { case ex: StaleSymbol => false diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index ce481759bd4d..69d9121a3d40 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1028,7 +1028,7 @@ object Types { val sym = lastSymbol if (sym == null) loadDenot else denotOfSym(sym) case d: SymDenotation => - if (d.validFor.runId == ctx.runId || ctx.stillValid(d)) d.current + if (ctx.isValidInRun(d)) d.current else { val newd = loadDenot if (newd.exists) newd else d.staleSymbolError From 456f292bd13e423091c7a1ef0963e3873f03f807 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Thu, 27 Mar 2014 12:53:03 +0100 Subject: [PATCH 6/6] Rename methods on FreshContext to make mutation obvious And avoid name clashes --- src/dotty/tools/dotc/Compiler.scala | 16 ++--- src/dotty/tools/dotc/Driver.scala | 2 +- .../tools/dotc/config/PathResolver.scala | 4 +- src/dotty/tools/dotc/core/Contexts.scala | 64 +++++++++---------- src/dotty/tools/dotc/core/Periods.scala | 2 +- src/dotty/tools/dotc/core/Phases.scala | 2 +- .../tools/dotc/core/SymDenotations.scala | 2 +- src/dotty/tools/dotc/core/TypeComparer.scala | 2 +- .../tools/dotc/printing/Disambiguation.scala | 2 +- src/dotty/tools/dotc/transform/LazyVals.scala | 4 +- src/dotty/tools/dotc/typer/Applications.scala | 4 +- src/dotty/tools/dotc/typer/FrontEnd.scala | 2 +- src/dotty/tools/dotc/typer/Implicits.scala | 18 +++--- src/dotty/tools/dotc/typer/Inferencing.scala | 2 +- src/dotty/tools/dotc/typer/Namer.scala | 14 ++-- src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 +- src/dotty/tools/dotc/typer/Typer.scala | 20 +++--- test/test/DottyTest.scala | 10 +-- test/test/ShowClassTests.scala | 4 +- 19 files changed, 88 insertions(+), 88 deletions(-) diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index 286ed34564ac..7b657b47be21 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -42,18 +42,18 @@ class Compiler { ctx.usePhases(phases) val rootScope = new MutableScope val bootstrap = ctx.fresh - .withPeriod(Period(nextRunId, FirstPhaseId)) - .withScope(rootScope) + .setPeriod(Period(nextRunId, FirstPhaseId)) + .setScope(rootScope) rootScope.enter(ctx.definitions.RootPackage)(bootstrap) val start = bootstrap.fresh - .withOwner(defn.RootClass) - .withTyper(new Typer) - .withNewMode(Mode.ImplicitsEnabled) - .withTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true)) + .setOwner(defn.RootClass) + .setTyper(new Typer) + .setMode(Mode.ImplicitsEnabled) + .setTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true)) ctx.definitions.init(start) // set context of definitions to start def addImport(ctx: Context, sym: Symbol) = - ctx.fresh.withImportInfo(ImportInfo.rootImport(sym)(ctx)) - (start.withRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport) + ctx.fresh.setImportInfo(ImportInfo.rootImport(sym)(ctx)) + (start.setRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport) } def newRun(implicit ctx: Context): Run = { diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 892e4cf7df71..5bf65544a562 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -24,7 +24,7 @@ abstract class Driver extends DotClass { def process(args: Array[String]): Reporter = { val summary = CompilerCommand.distill(args)(initCtx) - implicit val ctx: Context = initCtx.fresh.withSettings(summary.sstate) + implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate) val fileNames = CompilerCommand.checkUsage(summary) try { doCompile(newCompiler(), fileNames) diff --git a/src/dotty/tools/dotc/config/PathResolver.scala b/src/dotty/tools/dotc/config/PathResolver.scala index 73c045c774b6..34678ae2bf54 100644 --- a/src/dotty/tools/dotc/config/PathResolver.scala +++ b/src/dotty/tools/dotc/config/PathResolver.scala @@ -135,7 +135,7 @@ object PathResolver { def fromPathString(path: String)(implicit ctx: Context): JavaClassPath = { val settings = ctx.settings.classpath.update(path) - new PathResolver()(ctx.fresh.withSettings(settings)).result + new PathResolver()(ctx.fresh.setSettings(settings)).result } /** With no arguments, show the interesting values in Environment and Defaults. @@ -152,7 +152,7 @@ object PathResolver { val ArgsSummary(sstate, rest, errors) = ctx.settings.processArguments(args.toList, true) errors.foreach(println) - val pr = new PathResolver()(ctx.fresh.withSettings(sstate)) + val pr = new PathResolver()(ctx.fresh.setSettings(sstate)) println(" COMMAND: 'scala %s'".format(args.mkString(" "))) println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" "))) pr.result.show diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index da684ea9cfd3..12a83185e573 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -278,10 +278,10 @@ object Contexts { } final def withMode(mode: Mode): Context = - if (mode != this.mode) fresh.withNewMode(mode) else this + if (mode != this.mode) fresh.setMode(mode) else this final def withPhase(phase: PhaseId): Context = - if (this.phaseId == phaseId) this else fresh.withNewPhase(phase) + if (this.phaseId == phaseId) this else fresh.setPhase(phase) final def withPhase(phase: Phase): Context = withPhase(phase.id) @@ -306,36 +306,36 @@ object Contexts { * of its attributes using the with... methods. */ abstract class FreshContext extends Context { - def withPeriod(period: Period): this.type = { this.period = period; this } - def withNewMode(mode: Mode): this.type = { this.mode = mode; this } - def withTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this } - def withNewTyperState: this.type = withTyperState(typerState.fresh(isCommittable = true)) - def withExploreTyperState: this.type = withTyperState(typerState.fresh(isCommittable = false)) - def withPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this } - def withOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this } - def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this } - def withCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this } - def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this } - def withScope(scope: Scope): this.type = { this.scope = scope; this } - def withNewScope: this.type = { this.scope = newScope; this } - def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this } - def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) } - def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this } - def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } - def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } - def withTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } - def withSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } - def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this } - - def withProperty(prop: (String, Any)): this.type = withMoreProperties(moreProperties + prop) - - def withNewPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid)) - def withNewPhase(phase: Phase): this.type = withNewPhase(phase.id) - - def withSetting[T](setting: Setting[T], value: T): this.type = - withSettings(setting.updateIn(sstate, value)) - - def withDebug = withSetting(base.settings.debug, true) + def setPeriod(period: Period): this.type = { this.period = period; this } + def setMode(mode: Mode): this.type = { this.mode = mode; this } + def setTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this } + def clearTyperState: this.type = setTyperState(typerState.fresh(isCommittable = true)) + def setExploreTyperState: this.type = setTyperState(typerState.fresh(isCommittable = false)) + def setPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this } + def setOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this } + def setSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this } + def setCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this } + def setTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this } + def setScope(scope: Scope): this.type = { this.scope = scope; this } + def clearScope: this.type = { this.scope = newScope; this } + def setTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this } + def setTyper(typer: Typer): this.type = { this.scope = typer.scope; setTypeAssigner(typer) } + def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this } + def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } + def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } + def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } + def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } + def setMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this } + + def setProperty(prop: (String, Any)): this.type = setMoreProperties(moreProperties + prop) + + def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid)) + def setPhase(phase: Phase): this.type = setPhase(phase.id) + + def setSetting[T](setting: Setting[T], value: T): this.type = + setSettings(setting.updateIn(sstate, value)) + + def setDebug = setSetting(base.settings.debug, true) } /** A class defining the initial context with given context base diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala index 6e1522e269d0..370cc2b96059 100644 --- a/src/dotty/tools/dotc/core/Periods.scala +++ b/src/dotty/tools/dotc/core/Periods.scala @@ -19,7 +19,7 @@ abstract class Periods extends DotClass { self: Context => /** Execute `op` at given period */ def atPeriod[T](pd: Period)(op: Context => T): T = - op(ctx.fresh.withPeriod(pd)) + op(ctx.fresh.setPeriod(pd)) /** Execute `op` at given phase id */ def atPhase[T](pid: PhaseId)(op: Context => T): T = diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index ee993b8905bd..3de42fb4e944 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -163,7 +163,7 @@ object Phases { def run(implicit ctx: Context): Unit def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = - for (unit <- units) run(ctx.fresh.withNewPhase(this).withCompilationUnit(unit)) + for (unit <- units) run(ctx.fresh.setPhase(this).setCompilationUnit(unit)) def description: String = name diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 5c11b266eb8e..da624ffe55fa 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1357,7 +1357,7 @@ object SymDenotations { val (location, src) = if (file != null) (s" in $file", file.toString) else ("", "the signature") - val name = ctx.fresh.withSetting(ctx.settings.debugNames, true).nameString(denot.name) + val name = ctx.fresh.setSetting(ctx.settings.debugNames, true).nameString(denot.name) ctx.error( s"""|bad symbolic reference. A signature$location |refers to $name in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available. diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index ce1c1e869cde..cab09826b9b8 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1134,7 +1134,7 @@ object TypeComparer { /** Show trace of comparison operations when performing `op` as result string */ def explained[T](op: Context => T)(implicit ctx: Context): String = { - val nestedCtx = ctx.fresh.withTypeComparerFn(new ExplainingTypeComparer(_)) + val nestedCtx = ctx.fresh.setTypeComparerFn(new ExplainingTypeComparer(_)) op(nestedCtx) nestedCtx.typeComparer.toString } diff --git a/src/dotty/tools/dotc/printing/Disambiguation.scala b/src/dotty/tools/dotc/printing/Disambiguation.scala index b830b353ad93..baacee42fea4 100644 --- a/src/dotty/tools/dotc/printing/Disambiguation.scala +++ b/src/dotty/tools/dotc/printing/Disambiguation.scala @@ -75,7 +75,7 @@ object Disambiguation { def disambiguated(op: Context => String)(implicit ctx: Context): String = { val dctx = ctx.printer match { case dp: Printer => ctx - case _ => ctx.fresh.withPrinterFn(newPrinter) + case _ => ctx.fresh.setPrinterFn(newPrinter) } val res = op(dctx) dctx.printer match { diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala index ffc2096f1783..28a8d12d99f1 100644 --- a/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/src/dotty/tools/dotc/transform/LazyVals.scala @@ -249,7 +249,7 @@ class LazyValTranformContext { val flagSymbol = ctx.newSymbol(methodSymbol, "flag".toTermName, Flags.Mutable & Flags.Synthetic, defn.LongType) val flagDef = ValDef(flagSymbol, Literal(Constant(0L))) - val thiz = This(claz)(ctx.fresh.withOwner(claz)) + val thiz = This(claz)(ctx.fresh.setOwner(claz)) val resultSymbol = ctx.newSymbol(methodSymbol, "result".toTermName, Flags.Mutable & Flags.Synthetic, tp) val resultDef = ValDef(resultSymbol, Literal(initValue(tp.widen))) @@ -313,7 +313,7 @@ class LazyValTranformContext { val tpe = x.tpe.widen val claz = x.symbol.owner.asClass - val thiz = This(claz)(ctx.fresh.withOwner(claz)) + val thiz = This(claz)(ctx.fresh.setOwner(claz)) val companion = claz.companionModule val helperModule = ctx.requiredModule("dotty.runtime.LazyVals") val getOffset = Select(Ident(helperModule.termRef), LazyVals.Names.getOffset.toTermName) diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 46a6ebf66a16..9a21e1c54f68 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -712,7 +712,7 @@ trait Applications extends Compatibility { self: Typer => * @param resultType The expected result type of the application */ def isApplicable(methRef: TermRef, targs: List[Type], args: List[Tree], resultType: Type)(implicit ctx: Context): Boolean = { - val nestedContext = ctx.fresh.withExploreTyperState + val nestedContext = ctx.fresh.setExploreTyperState new ApplicableToTrees(methRef, targs, args, resultType)(nestedContext).success } @@ -720,7 +720,7 @@ trait Applications extends Compatibility { self: Typer => * @param resultType The expected result type of the application */ def isApplicable(methRef: TermRef, args: List[Type], resultType: Type)(implicit ctx: Context): Boolean = { - val nestedContext = ctx.fresh.withExploreTyperState + val nestedContext = ctx.fresh.setExploreTyperState new ApplicableToTypes(methRef, args, resultType)(nestedContext).success } diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala index 0161c1f6ffd2..697830fb1b71 100644 --- a/src/dotty/tools/dotc/typer/FrontEnd.scala +++ b/src/dotty/tools/dotc/typer/FrontEnd.scala @@ -41,7 +41,7 @@ class FrontEnd extends Phase { } override def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = { - val unitContexts = units map (unit => ctx.fresh.withCompilationUnit(unit)) + val unitContexts = units map (unit => ctx.fresh.setCompilationUnit(unit)) unitContexts foreach (parse(_)) record("parsedTrees", ast.Trees.ntrees) unitContexts foreach (enterSyms(_)) diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index fe1c938c9b44..8990d21a24d0 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -50,13 +50,13 @@ object Implicits { case mt: MethodType => mt.isImplicit || mt.paramTypes.length != 1 || - !(argType <:< mt.paramTypes.head)(ctx.fresh.withExploreTyperState) + !(argType <:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState) case poly: PolyType => poly.resultType match { case mt: MethodType => mt.isImplicit || mt.paramTypes.length != 1 || - !(argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.withExploreTyperState)) + !(argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.setExploreTyperState)) case rtp => discardForView(wildApprox(rtp), argType) } @@ -90,7 +90,7 @@ object Implicits { } if (refs.isEmpty) refs - else refs filter (refMatches(_)(ctx.fresh.withExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution + else refs filter (refMatches(_)(ctx.fresh.setExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution } } @@ -370,7 +370,7 @@ trait Implicits { self: Typer => } case _ => } - inferView(dummyTreeOfType(from), to)(ctx.fresh.withExploreTyperState).isInstanceOf[SearchSuccess] + inferView(dummyTreeOfType(from), to)(ctx.fresh.setExploreTyperState).isInstanceOf[SearchSuccess] } ) @@ -419,7 +419,7 @@ trait Implicits { self: Typer => /** An implicit search; parameters as in `inferImplicit` */ class ImplicitSearch(protected val pt: Type, protected val argument: Tree, pos: Position)(implicit ctx: Context) { - private def nestedContext = ctx.fresh.withNewMode(ctx.mode &~ Mode.ImplicitsEnabled) + private def nestedContext = ctx.fresh.setMode(ctx.mode &~ Mode.ImplicitsEnabled) private def implicitProto(resultType: Type, f: Type => Type) = if (argument.isEmpty) f(resultType) else ViewProto(f(argument.tpe.widen), f(resultType)) @@ -457,7 +457,7 @@ trait Implicits { self: Typer => pt) val generated1 = adapt(generated, pt) lazy val shadowing = - typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.withNewTyperState) + typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.clearTyperState) def refMatches(shadowing: Tree): Boolean = ref.symbol == closureBody(shadowing).symbol || { shadowing match { @@ -485,12 +485,12 @@ trait Implicits { self: Typer => val history = ctx.searchHistory nest wildProto val result = if (history eq ctx.searchHistory) divergingImplicit(ref) - else typedImplicit(ref)(nestedContext.withNewTyperState.withSearchHistory(history)) + else typedImplicit(ref)(nestedContext.clearTyperState.setSearchHistory(history)) result match { case fail: SearchFailure => rankImplicits(pending1, acc) case best: SearchSuccess => - val newPending = pending1 filter (isAsGood(_, best.ref)(nestedContext.withExploreTyperState)) + val newPending = pending1 filter (isAsGood(_, best.ref)(nestedContext.setExploreTyperState)) rankImplicits(newPending, best :: acc) } case nil => acc @@ -499,7 +499,7 @@ trait Implicits { self: Typer => /** Convert a (possibly empty) list of search successes into a single search result */ def condense(hits: List[SearchSuccess]): SearchResult = hits match { case best :: alts => - alts find (alt => isAsGood(alt.ref, best.ref)(ctx.fresh.withExploreTyperState)) match { + alts find (alt => isAsGood(alt.ref, best.ref)(ctx.fresh.setExploreTyperState)) match { case Some(alt) => /* !!! DEBUG println(i"ambiguous refs: ${hits map (_.ref) map (_.show) mkString ", "}") diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 6d9afecabb20..9c4ce232e344 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -30,7 +30,7 @@ trait Inferencing { this: Checking => * Variables that are successfully minimized do not count as uninstantiated. */ def isFullyDefined(tp: Type, force: ForceDegree.Value)(implicit ctx: Context): Boolean = { - val nestedCtx = ctx.fresh.withNewTyperState + val nestedCtx = ctx.fresh.clearTyperState val result = new IsFullyDefinedAccumulator(force)(nestedCtx).process(tp) if (result) nestedCtx.typerState.commit() result diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 361de802c742..e81949f05e4e 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -288,11 +288,11 @@ class Namer { typer: Typer => /** A new context that summarizes an import statement */ def importContext(sym: Symbol, selectors: List[Tree])(implicit ctx: Context) = - ctx.fresh.withImportInfo(new ImportInfo(sym, selectors)) + ctx.fresh.setImportInfo(new ImportInfo(sym, selectors)) /** A new context for the interior of a class */ def inClassContext(selfInfo: DotClass /* Should be Type | Symbol*/)(implicit ctx: Context): Context = { - val localCtx: Context = ctx.fresh.withNewScope + val localCtx: Context = ctx.fresh.clearScope selfInfo match { case sym: Symbol if sym.exists && sym.name != nme.WILDCARD => localCtx.scope.asInstanceOf[MutableScope].enter(sym) @@ -330,7 +330,7 @@ class Namer { typer: Typer => def indexExpanded(stat: Tree)(implicit ctx: Context): Context = expanded(stat) match { case pcl: PackageDef => val pkg = createPackageSymbol(pcl.pid) - index(pcl.stats)(ctx.fresh.withOwner(pkg.moduleClass)) + index(pcl.stats)(ctx.fresh.setOwner(pkg.moduleClass)) invalidateCompanions(pkg, Trees.flatten(pcl.stats map expanded)) ctx case imp: Import => @@ -380,19 +380,19 @@ class Namer { typer: Typer => /** The completer of a symbol defined by a member def or import (except ClassSymbols) */ class Completer(val original: Tree)(implicit ctx: Context) extends LazyType { - protected def localContext(owner: Symbol) = ctx.fresh.withOwner(owner).withTree(original) + protected def localContext(owner: Symbol) = ctx.fresh.setOwner(owner).setTree(original) private def typeSig(sym: Symbol): Type = original match { case original: ValDef => if (sym is Module) moduleValSig(sym) - else valOrDefDefSig(original, sym, Nil, identity)(localContext(sym).withNewScope) + else valOrDefDefSig(original, sym, Nil, identity)(localContext(sym).clearScope) case original: DefDef => val typer1 = new Typer nestedTyper(sym) = typer1 - typer1.defDefSig(original, sym)(localContext(sym).withTyper(typer1)) + typer1.defDefSig(original, sym)(localContext(sym).setTyper(typer1)) case original: TypeDef => assert(!original.isClassDef) - typeDefSig(original, sym)(localContext(sym).withNewScope) + typeDefSig(original, sym)(localContext(sym).clearScope) case imp: Import => try { val expr1 = typedAheadExpr(imp.expr, AnySelectionProto) diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 16fcc9db7cd1..16869454f35b 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -38,7 +38,7 @@ object ProtoTypes { /** Test compatibility after normalization in a fresh typerstate. */ def normalizedCompatible(tp: Type, pt: Type)(implicit ctx: Context) = { - val nestedCtx = ctx.fresh.withExploreTyperState + val nestedCtx = ctx.fresh.setExploreTyperState isCompatible(normalize(tp, pt)(nestedCtx), pt)(nestedCtx) } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 7c301a7f1ab7..0ba53f8c00ea 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -587,7 +587,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit assignType(cpy.CaseDef(tree, pat, guard1, body1), body1) } val doCase: () => CaseDef = - () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.withNewScope) + () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.clearScope) (doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))() } @@ -835,7 +835,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val pid1 = typedExpr(tree.pid, AnySelectionProto) val pkg = pid1.symbol val packageContext = - if (pkg is Package) ctx.fresh.withOwner(pkg.moduleClass).withTree(tree) + if (pkg is Package) ctx.fresh.setOwner(pkg.moduleClass).setTree(tree) else { ctx.error(i"$pkg is not a packge", tree.pos) ctx @@ -872,8 +872,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit NoSymbol } def localContext = { - val freshCtx = ctx.fresh.withTree(xtree) - if (sym.exists) freshCtx.withOwner(sym) + val freshCtx = ctx.fresh.setTree(xtree) + if (sym.exists) freshCtx.setOwner(sym) else freshCtx // can happen for self defs } @@ -884,13 +884,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case tree: untpd.Bind => typedBind(tree, pt) case tree: untpd.ValDef => if (tree.isEmpty) tpd.EmptyValDef - else typedValDef(tree, sym)(localContext.withNewScope) + else typedValDef(tree, sym)(localContext.clearScope) case tree: untpd.DefDef => val typer1 = nestedTyper.remove(sym).get - typer1.typedDefDef(tree, sym)(localContext.withTyper(typer1)) + typer1.typedDefDef(tree, sym)(localContext.setTyper(typer1)) case tree: untpd.TypeDef => if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext) - else typedTypeDef(tree, sym)(localContext.withNewScope) + else typedTypeDef(tree, sym)(localContext.clearScope) case _ => typedUnadapted(desugar(tree), pt) } @@ -904,7 +904,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case tree: untpd.Typed => typedTyped(tree, pt) case tree: untpd.NamedArg => typedNamedArg(tree, pt) case tree: untpd.Assign => typedAssign(tree, pt) - case tree: untpd.Block => typedBlock(desugar.block(tree), pt)(ctx.fresh.withNewScope) + case tree: untpd.Block => typedBlock(desugar.block(tree), pt)(ctx.fresh.clearScope) case tree: untpd.If => typedIf(tree, pt) case tree: untpd.Function => typedFunction(tree, pt) case tree: untpd.Closure => typedClosure(tree, pt) @@ -970,7 +970,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case Thicket(stats) :: rest => traverse(stats ++ rest) case stat :: rest => - val nestedCtx = if (exprOwner == ctx.owner) ctx else ctx.fresh.withOwner(exprOwner) + val nestedCtx = if (exprOwner == ctx.owner) ctx else ctx.fresh.setOwner(exprOwner) buf += typed(stat)(nestedCtx) traverse(rest) case nil => @@ -987,7 +987,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit typed(tree, pt)(ctx addMode Mode.Pattern) def tryEither[T](op: Context => T)(fallBack: (T, TyperState) => T)(implicit ctx: Context) = { - val nestedCtx = ctx.fresh.withNewTyperState + val nestedCtx = ctx.fresh.clearTyperState val result = op(nestedCtx) if (nestedCtx.reporter.hasErrors) fallBack(result, nestedCtx.typerState) diff --git a/test/test/DottyTest.scala b/test/test/DottyTest.scala index fcc211175315..604f5d500b7f 100644 --- a/test/test/DottyTest.scala +++ b/test/test/DottyTest.scala @@ -22,14 +22,14 @@ class DottyTest { val base = new ContextBase import base.settings._ val ctx = base.initialCtx.fresh - .withSetting(verbose, true) + .setSetting(verbose, true) // .withSetting(debug, true) // .withSetting(debugTrace, true) // .withSetting(prompt, true) - .withSetting(Ylogcp, true) - .withSetting(printtypes, true) - .withSetting(pageWidth, 90) - .withSetting(log, List(" Unit)(implicit ctx: Context): Unit = { - test(ctx.fresh.withSetting(ctx.base.settings.debug, true)) - test(ctx.fresh.withSetting(ctx.base.settings.debug, false)) + test(ctx.fresh.setSetting(ctx.base.settings.debug, true)) + test(ctx.fresh.setSetting(ctx.base.settings.debug, false)) } def showPackage(pkg: TermSymbol)(implicit ctx: Context): Unit = {