diff options
author | Martin Odersky <odersky@gmail.com> | 2014-03-10 22:42:39 +0100 |
---|---|---|
committer | Tobias Schlatter <tobias@meisch.ch> | 2014-03-20 20:25:05 +0100 |
commit | 5b687fbee23060fbed285f090e3592f2b8cb6beb (patch) | |
tree | 85b63c2f90e813db42adb3b327f542e389640b20 /src/dotty | |
parent | 3ba0931636a5d34ca2da9588f2952af709d41ace (diff) | |
download | dotty-5b687fbee23060fbed285f090e3592f2b8cb6beb.tar.gz dotty-5b687fbee23060fbed285f090e3592f2b8cb6beb.tar.bz2 dotty-5b687fbee23060fbed285f090e3592f2b8cb6beb.zip |
Generalize derived type tree scheme.
To get truly hygienic desugared trees, we need a derived type tree scheme that's more
flexible than just the previous two choices of info-of-symbol and typeref-of-symbol.
The new scheme based on DerivedTypeTrees allows arbitrary methods to derive the type tree's type.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 32 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 25 |
3 files changed, 25 insertions, 34 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index e8099f360..4a635d259 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -24,16 +24,6 @@ object desugar { // ----- TypeTrees that refer to other tree's symbols ------------------- - /** A marker tree used as the original for TypeTrees that get their type by taking - * the typeRef of some other tree's symbol. (currently unused) - */ - val TypeRefOfSym = new TypeTree(EmptyTree) - - /** A marker tree used as the original for TypeTrees that get their type by taking - * the result type of the info of some other tree's symbol. - */ - val InfoOfSym = new TypeTree(EmptyTree) - /** Attachment key containing TypeTrees whose type is computed * from the symbol in this type. These type trees have marker trees * TypeRefOfSym or InfoOfSym as their originals. @@ -46,15 +36,19 @@ object desugar { */ val OriginalSymbol = new Attachment.Key[Symbol] - /** A type tree that is marked to get its type by taking - * the typeRef of some other tree's symbol. Enters the type tree - * in the References attachment of the `original` tree as a side effect. + /** A type tree that gets its type from some other tree's symbol. Enters the + * type tree in the References attachment of the `from` tree as a side effect. */ - def refTypeTree(original: Tree, marker: TypeTree): TypeTree = { - val result = TypeTree(marker) - val existing = original.attachmentOrElse(References, Nil) - original.putAttachment(References, result :: existing) - result + abstract class DerivedTypeTree(from: Tree) extends TypeTree(EmptyTree) { + val existing = from.attachmentOrElse(References, Nil) + from.putAttachment(References, this :: existing) + + /** The method that computes the type of this tree */ + def derivedType(originalSym: Symbol)(implicit ctx: Context): Type + } + + class SetterParam(vdef: ValDef) extends DerivedTypeTree(vdef) { + def derivedType(vsym: Symbol)(implicit ctx: Context) = vsym.info.resultType } // ----- Desugar methods ------------------------------------------------- @@ -73,7 +67,7 @@ object desugar { // val getter = ValDef(mods, name, tpt, rhs) withPos vdef.pos ? // right now vdef maps via expandedTree to a thicket which concerns itself. // I don't see a problem with that but if there is one we can avoid it by making a copy here. - val setterParam = makeSyntheticParameter(tpt = refTypeTree(vdef, InfoOfSym)) + val setterParam = makeSyntheticParameter(tpt = new SetterParam(vdef)) val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else unitLiteral val setter = cpy.DefDef(vdef, mods | Accessor, name.setterName, Nil, (setterParam :: Nil) :: Nil, diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 21b87aee4..162e13bbc 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -458,6 +458,8 @@ class Namer { typer: Typer => index(constr) index(rest)(inClassContext(selfInfo)) denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) + // make sure constr parameters are all entered because we refer to them in desugarings: + symbolOfTree(constr).ensureCompleted() } } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 32e847757..e9a79eeb1 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -635,23 +635,18 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") { - if (tree.original.isEmpty) { - def symbol = tree.attachment(desugar.OriginalSymbol) - // btw, no need to remove the attachment. The typed - // tree is different from the untyped one, so the - // untyped tree is no longer accessed after all - // accesses with typedTypeTree are done. - val ownType = tree.original match { - case untpd.EmptyTree => + if (tree.original.isEmpty) + tree match { + case tree: desugar.DerivedTypeTree => + TypeTree(tree.derivedType(tree.attachment(desugar.OriginalSymbol))) withPos tree.pos + // btw, no need to remove the attachment. The typed + // tree is different from the untyped one, so the + // untyped tree is no longer accessed after all + // accesses with typedTypeTree are done. + case _ => assert(isFullyDefined(pt, ForceDegree.none)) - pt - case desugar.TypeRefOfSym => - symbol.typeRef - case desugar.InfoOfSym => - symbol.info.resultType + tree.withType(pt) } - cpy.TypeTree(tree, untpd.EmptyTree).withType(ownType) - } else { val original1 = typed(tree.original) cpy.TypeTree(tree, original1).withType(original1.tpe) |