Skip to content

Commit

Permalink
Retract InTypeOf correctly during unpickling
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierBlanvillain committed Aug 24, 2018
1 parent 3bf80c9 commit 4fa9403
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 11 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ object Trees {
case TypeTree() =>
tree
case SingletonTypeTree(ref) =>
cpy.SingletonTypeTree(tree)(transform(ref)(ctx.fresh.addMode(Mode.InTypeOf)))
cpy.SingletonTypeTree(tree)(transform(ref)(ctx.enterTypeOf()))
case AndTypeTree(left, right) =>
cpy.AndTypeTree(tree)(transform(left), transform(right))
case OrTypeTree(left, right) =>
Expand Down
13 changes: 12 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ object Contexts {
protected def owner_=(owner: Symbol) = _owner = owner
def owner: Symbol = _owner

/** The owner at the point of entering TypeOf (for SingletonTypeTrees) */
private[this] var _inTypeOfOwner: Symbol = _
protected def inTypeOfOwner_=(owner: Symbol) = _inTypeOfOwner = owner
def inTypeOfOwner: Symbol = _inTypeOfOwner

/** The current tree */
private[this] var _tree: Tree[_ >: Untyped]= _
protected def tree_=(tree: Tree[_ >: Untyped]) = _tree = tree
Expand Down Expand Up @@ -179,12 +184,15 @@ object Contexts {
* dependent, we finally also compute `_dependent` based on this context.
*/
if (!_dependentInit) {
_dependent = this.mode.is(Mode.InTypeOf) || isDepOwner(this.owner)
_dependent = this.isInTypeOf || isDepOwner(this.owner)
_dependentInit = true
}
_dependent
}

final def isInTypeOf: Boolean =
this.inTypeOfOwner == this.owner

/** A map in which more contextual properties can be stored
* Typically used for attributes that are read and written only in special situations.
*/
Expand Down Expand Up @@ -497,6 +505,7 @@ object Contexts {
def setPeriod(period: Period): this.type = { this.period = period; this }
def setMode(mode: Mode): this.type = { this.mode = mode; this }
def setOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
def enterTypeOf(): this.type = { assert(this.owner != NoSymbol); this.inTypeOfOwner = this.owner; this }
def setTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
def setScope(scope: Scope): this.type = { this.scope = scope; this }
def setNewScope: this.type = { this.scope = newScope; this }
Expand Down Expand Up @@ -561,6 +570,8 @@ object Contexts {
final def addMode(mode: Mode): Context = withModeBits(c.mode | mode)
final def maskMode(mode: Mode): Context = withModeBits(c.mode & mode)
final def retractMode(mode: Mode): Context = withModeBits(c.mode &~ mode)

final def enterTypeOf(): Context = if (c.isInTypeOf) c else c.fresh.enterTypeOf()
}

implicit class FreshModeChanges(val c: FreshContext) extends AnyVal {
Expand Down
11 changes: 4 additions & 7 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4084,9 +4084,6 @@ object Types {
} else
tp

private def dependently(implicit ctx: Context): Context =
ctx.addMode(Mode.InTypeOf)

object If {
def apply(underlyingTp: Type, condTp: Type, thenTp: Type, elseTp: Type)(implicit ctx: Context): TypeOf =
TypeOf(underlyingTp, untpd.If(
Expand All @@ -4107,7 +4104,7 @@ object Types {
treeWithTpe(cond, condTp),
treeWithTpe(thenp, thenTp),
treeWithTpe(elsep, elseTp)
)(dependently)
)(ctx.enterTypeOf())
})
}

Expand All @@ -4126,7 +4123,7 @@ object Types {
def derived(to: TypeOf)(selectorTp: Type, caseTps: List[Type])(implicit ctx: Context): Type =
finalizeDerived(to, to.tree match {
case Trees.Match(selector, cases) =>
cpy.Match(to.tree)(treeWithTpe(selector, selectorTp), treesWithTpes(cases, caseTps))(dependently)
cpy.Match(to.tree)(treeWithTpe(selector, selectorTp), treesWithTpes(cases, caseTps))(ctx.enterTypeOf())
})
}

Expand All @@ -4145,7 +4142,7 @@ object Types {
def derived(to: TypeOf)(funTp: Type, argTps: List[Type])(implicit ctx: Context): Type =
finalizeDerived(to, to.tree match {
case Trees.Apply(fun, args) =>
cpy.Apply(to.tree)(treeWithTpe(fun, funTp), treesWithTpes(args, argTps))(dependently)
cpy.Apply(to.tree)(treeWithTpe(fun, funTp), treesWithTpes(args, argTps))(ctx.enterTypeOf())
})
}

Expand All @@ -4164,7 +4161,7 @@ object Types {
def derived(to: TypeOf)(funTp: Type, argTps: List[Type])(implicit ctx: Context): Type =
finalizeDerived(to, to.tree match {
case Trees.TypeApply(fun, args) =>
cpy.TypeApply(to.tree)(treeWithTpe(fun, funTp), treesWithTpes(args, argTps))(dependently)
cpy.TypeApply(to.tree)(treeWithTpe(fun, funTp), treesWithTpes(args, argTps))(ctx.enterTypeOf())
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ class TreeUnpickler(reader: TastyReader,
case THROW =>
Throw(readTerm())
case SINGLETONtpt =>
SingletonTypeTree(readTerm()(ctx.fresh.addMode(Mode.InTypeOf)))
SingletonTypeTree(readTerm()(ctx.enterTypeOf()))
case BYNAMEtpt =>
ByNameTypeTree(readTpt())
case NAMEDARG =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ class Typer extends Namer
}

def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") {
val ref1 = typedExpr(tree.ref)(ctx.fresh.addMode(Mode.InTypeOf))
val ref1 = typedExpr(tree.ref)(ctx.enterTypeOf())
// TODO: Discuss stability requirements of singleton type trees and potentially reenable check
// checkStable(ref1.tpe, tree.pos)
assignType(cpy.SingletonTypeTree(tree)(ref1), ref1)
Expand Down

0 comments on commit 4fa9403

Please sign in to comment.