diff options
author | Martin Odersky <odersky@gmail.com> | 2015-06-18 13:27:43 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-06-22 11:40:20 +0200 |
commit | 131ab5c1261608715cf2fde3aa44a04777cbda64 (patch) | |
tree | 3f878ca320f25d064e39d8c1846e0885303da589 /src/dotty | |
parent | 6f4b38cf9d1711ec525219d9b0b8049c95047f38 (diff) | |
download | dotty-131ab5c1261608715cf2fde3aa44a04777cbda64.tar.gz dotty-131ab5c1261608715cf2fde3aa44a04777cbda64.tar.bz2 dotty-131ab5c1261608715cf2fde3aa44a04777cbda64.zip |
Avoid double context creation when modes change on a fresh context.
Move addMode and friends to two decorators, one for Context, the other
for FreshContext. Implement behavior accordingly.
This avoids creating two contexts in situations like:
c.fresh.setxploreTyperState.addMode(...)
Mow we can write
c.fresh.addMode(...).setExploreTyperState
Because addMode returns a fresh context when applied to a fresh context.
Note that we specifically do not want virtual dispatch of addMode, that's
why it was moved to a decorator.
Also: removed mention of ".fresh: when just forllowed by an addMode, because
that one is redundant.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 22 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/PlainPrinter.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 |
4 files changed, 20 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index b00896117..c9deaab10 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -386,13 +386,6 @@ object Contexts { final def withOwner(owner: Symbol): Context = if (owner ne this.owner) fresh.setOwner(owner) else this - final def withMode(mode: Mode): Context = - if (mode != this.mode) fresh.setMode(mode) else this - - final def addMode(mode: Mode): Context = withMode(this.mode | mode) - final def maskMode(mode: Mode): Context = withMode(this.mode & mode) - final def retractMode(mode: Mode): Context = withMode(this.mode &~ mode) - override def toString = "Context(\n" + (outersIterator map ( ctx => s" owner = ${ctx.owner}, scope = ${ctx.scope}") mkString "\n") @@ -444,6 +437,21 @@ object Contexts { def setDebug = setSetting(base.settings.debug, true) } + implicit class ModeChanges(val c: Context) extends AnyVal { + final def withMode(mode: Mode): Context = + if (mode != c.mode) c.fresh.setMode(mode) else c + + final def addMode(mode: Mode): Context = withMode(c.mode | mode) + final def maskMode(mode: Mode): Context = withMode(c.mode & mode) + final def retractMode(mode: Mode): Context = withMode(c.mode &~ mode) + } + + implicit class FreshModeChanges(val c: FreshContext) extends AnyVal { + final def addMode(mode: Mode): c.type = c.setMode(c.mode | mode) + final def maskMode(mode: Mode): c.type = c.setMode(c.mode & mode) + final def retractMode(mode: Mode): c.type = c.setMode(c.mode &~ mode) + } + /** A class defining the initial context with given context base * and set of possible settings. */ diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index 86dd3878c..5d2309e95 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -12,7 +12,7 @@ import typer.Mode import scala.annotation.switch class PlainPrinter(_ctx: Context) extends Printer { - protected[this] implicit def ctx: Context = _ctx.fresh.addMode(Mode.Printing) + protected[this] implicit def ctx: Context = _ctx.addMode(Mode.Printing) protected def maxToTextRecursions = 100 diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 43d93b2b8..be76553be 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -90,7 +90,7 @@ object Implicits { } if (refs.isEmpty) refs - else refs filter (refMatches(_)(ctx.fresh.setExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution + else refs filter (refMatches(_)(ctx.fresh.addMode(Mode.TypevarsMissContext).setExploreTyperState)) // create a defensive copy of ctx to avoid constraint pollution } } @@ -480,7 +480,8 @@ trait Implicits { self: Typer => pt) val generated1 = adapt(generated, pt) lazy val shadowing = - typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto)(nestedContext.setNewTyperState.addMode(Mode.ImplicitShadowing)) + typed(untpd.Ident(ref.name) withPos pos.toSynthetic, funProto) + (nestedContext.addMode(Mode.ImplicitShadowing).setNewTyperState) def refMatches(shadowing: Tree): Boolean = ref.symbol == closureBody(shadowing).symbol || { shadowing match { diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 11a0bd76e..d5a6ec8f4 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -701,7 +701,7 @@ class Namer { typer: Typer => // println(s"final inherited for $sym: ${inherited.toString}") !!! // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}") - val rhsCtx = ctx.fresh addMode Mode.InferringReturnType + val rhsCtx = ctx.addMode(Mode.InferringReturnType) def rhsType = ctx.deskolemize( typedAheadExpr(mdef.rhs, rhsProto)(rhsCtx).tpe.widen.approximateUnion) def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos) |