diff options
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 40 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ReTyper.scala | 56 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 74 |
3 files changed, 101 insertions, 69 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index b403d4e66..d4156e1d7 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -158,27 +158,18 @@ object Erasure { cast(tree, pt) } - class Typer extends typer.Typer with NoChecking { + class Typer extends typer.ReTyper with NoChecking { import Boxing._ - def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = - erasure(tree.tpe.asInstanceOf[Type]) + def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = erasure(tree.typeOpt) - private def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = { + override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = { assert(tree.hasType) val erased = erasedType(tree)(ctx.withPhase(ctx.erasurePhase)) ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}") tree.withType(erased) } - override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = { - val tree1 = promote(tree) - tree1.tpe match { - case ThisType(cls) => This(cls) withPos tree.pos - case _ => tree1 - } - } - /** Type check select nodes, applying the following rewritings exhaustively * on selections `e.m`. * @@ -263,12 +254,8 @@ object Erasure { super.typedDefDef(ddef1, sym) } - override def typedClassDef(cdef: untpd.TypeDef, sym: ClassSymbol)(implicit ctx: Context) = { - val TypeDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef - val cdef1 = untpd.cpy.TypeDef(cdef, mods, name, - untpd.cpy.Template(impl, constr, parents, untpd.EmptyValDef, body)) - super.typedClassDef(cdef1, sym) - } + override def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context) = + EmptyTree /* override def transformStats(stats: List[Tree], exprOwner: Symbol)(implicit ctx: Context) = { @@ -276,28 +263,11 @@ object Erasure { if (ctx.owner.isClass) addBridges(stats1) else stats1 } */ - override def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = { - if (tree eq untpd.EmptyValDef) return tpd.EmptyValDef - assert(tree.hasType, tree.show) - val sym = tree.symbol - def localContext = ctx.fresh.setTree(tree).setOwner(sym) - tree match { - case tree: untpd.Ident => typedIdent(tree, pt) - case tree: untpd.Select => typedSelect(tree, pt) - case tree: untpd.ValDef => typedValDef(tree, sym)(localContext) - case tree: untpd.DefDef => typedDefDef(tree, sym)(localContext) - case tree: untpd.TypeDef => - if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext) - else EmptyTree - } - } override def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = ctx.traceIndented(i"adapting ${tree.showSummary}: ${tree.tpe} to $pt", show = true) { assert(ctx.phase == ctx.erasurePhase.next, ctx.phase) if (tree.isEmpty) tree else adaptToType(tree, pt) } - - override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala new file mode 100644 index 000000000..896dbba7d --- /dev/null +++ b/src/dotty/tools/dotc/typer/ReTyper.scala @@ -0,0 +1,56 @@ +package dotty.tools.dotc +package typer + +import core.Contexts._ +import core.Types._ +import core.Symbols.Symbol +import typer.ProtoTypes._ +import ast.{tpd, untpd} +import ast.Trees._ + +/** A version of Typer that keeps all symbols defined and referenced in a + * previously typed tree. + * + * All definition nodes keep their symbols. All leaf nodes for idents, selects, + * and TypeTrees keep their types. Indexing is a no-op. + * + * Otherwise, everything is as in Typer. + */ +class ReTyper extends Typer { + import tpd._ + + protected def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = { + assert(tree.hasType) + tree.withType(tree.typeOpt) + } + + override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = + promote(tree) + + override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = { + assert(tree.hasType) + val qual1 = typed(tree.qualifier, AnySelectionProto) + untpd.cpy.Select(tree, qual1, tree.name).withType(tree.typeOpt) + } + + override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = { + assert(tree.hasType) + val qual1 = typed(tree.qualifier, AnySelectionProto) + untpd.cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(tree.typeOpt) + } + + override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = + promote(tree) + + override def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = { + assert(tree.hasType) + val body1 = typed(tree.body, pt) + untpd.cpy.Bind(tree, tree.name, body1).withType(tree.typeOpt) + } + + override def retrieveSym(tree: untpd.Tree)(implicit ctx: Context): Symbol = tree.symbol + + override def localTyper(sym: Symbol) = this + + override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx +}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index b72cd0fa8..c2488f68c 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -775,7 +775,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit //todo: make sure dependent method types do not depend on implicits or by-name params } - def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = track("typedTypeDef") { + def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedTypeDef") { val TypeDef(mods, name, rhs) = tdef val mods1 = typedModifiers(mods) val _ = typedType(rhs) // unused, typecheck only to remove from typedTree @@ -858,40 +858,26 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedAsFunction(tree: untpd.Tree, pt: Type)(implicit ctx: Context): Tree = typed(tree, if (defn.isFunctionType(pt)) pt else AnyFunctionProto) - def typedNamed(xtree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = { - val tree = xtree withName xtree.name.encode - val sym = xtree.removeAttachment(SymOfTree) match { - case Some(sym) => - sym.ensureCompleted() - sym - case none => - NoSymbol - } - - def localContext = { - val freshCtx = ctx.fresh.setTree(xtree) - if (sym.exists) freshCtx.setOwner(sym) - else freshCtx // can happen for self defs - } + /** Retrieve symbol attached to given tree */ + protected def retrieveSym(tree: untpd.Tree)(implicit ctx: Context) = tree.removeAttachment(SymOfTree) match { + case Some(sym) => + sym.ensureCompleted() + sym + case none => + NoSymbol + } - tree match { - case tree: untpd.Ident => typedIdent(tree, pt) - case tree: untpd.Select => typedSelect(tree, pt) - case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt) - case tree: untpd.Bind => typedBind(tree, pt) - case tree: untpd.ValDef => - if (tree.isEmpty) tpd.EmptyValDef - else typedValDef(tree, sym)(localContext.setNewScope) - case tree: untpd.DefDef => - val typer1 = nestedTyper.remove(sym).get - typer1.typedDefDef(tree, sym)(localContext.setTyper(typer1)) - case tree: untpd.TypeDef => - if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext) - else typedTypeDef(tree, sym)(localContext.setNewScope) - case _ => typedUnadapted(desugar(tree), pt) - } + /** A fresh local context with given tree and owner. + * Owner might not exist (can happen for self valdefs), in which case + * no owner is set in result context + */ + protected def localContext(tree: untpd.Tree, owner: Symbol)(implicit ctx: Context): FreshContext = { + val freshCtx = ctx.fresh.setTree(tree) + if (owner.exists) freshCtx.setOwner(owner) else freshCtx } + protected def localTyper(sym: Symbol): Typer = nestedTyper.remove(sym).get + def typedUnadapted(initTree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = { record("typedUnadapted") val xtree = expanded(initTree) @@ -899,6 +885,26 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case Some(ttree) => ttree case none => + def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = { + val sym = retrieveSym(xtree) + tree match { + case tree: untpd.Ident => typedIdent(tree, pt) + case tree: untpd.Select => typedSelect(tree, pt) + case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt) + case tree: untpd.Bind => typedBind(tree, pt) + case tree: untpd.ValDef => + if (tree.isEmpty) tpd.EmptyValDef + else typedValDef(tree, sym)(localContext(tree, sym).setNewScope) + case tree: untpd.DefDef => + val typer1 = localTyper(sym) + typer1.typedDefDef(tree, sym)(localContext(tree, sym).setTyper(typer1)) + case tree: untpd.TypeDef => + if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext(tree, sym)) + else typedTypeDef(tree, sym)(localContext(tree, sym).setNewScope) + case _ => typedUnadapted(desugar(tree), pt) + } + } + def typedUnnamed(tree: untpd.Tree): Tree = tree match { case tree: untpd.Apply => if (ctx.mode is Mode.Pattern) typedUnApply(tree, pt) else typedApply(tree, pt) @@ -938,8 +944,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } xtree match { - case xtree: untpd.NameTree => typedNamed(xtree, pt) - case xtree: untpd.Import => typedImport(xtree, xtree.removeAttachment(SymOfTree).get) + case xtree: untpd.NameTree => typedNamed(xtree withName xtree.name.encode, pt) + case xtree: untpd.Import => typedImport(xtree, retrieveSym(xtree)) case xtree => typedUnnamed(xtree) } } |