aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-10 22:06:13 +0100
committerTobias Schlatter <tobias@meisch.ch>2014-03-20 20:25:05 +0100
commit3ba0931636a5d34ca2da9588f2952af709d41ace (patch)
treecc80be514102bca1203cc6a83a8fd62c7e0ae6c8 /src/dotty/tools/dotc
parentce466da9fd5b2601c91e351fd1d288099ec380b2 (diff)
downloaddotty-3ba0931636a5d34ca2da9588f2952af709d41ace.tar.gz
dotty-3ba0931636a5d34ca2da9588f2952af709d41ace.tar.bz2
dotty-3ba0931636a5d34ca2da9588f2952af709d41ace.zip
New scheme for TypeTrees that refer to others
Adds a new scheme by which a TypeTree() can refer for its type to the symbol of some other type. Applies the scheme to setter parameters, replacing the previous ad-hoc solution.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala40
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala12
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala26
4 files changed, 68 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 0c741a652..e8099f360 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -6,6 +6,7 @@ import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
import Decorators._
+import util.Attachment
import language.higherKinds
import collection.mutable.ListBuffer
import typer.ErrorReporting.InfoString
@@ -21,6 +22,43 @@ object desugar {
/** Info of a variable in a pattern: The named tree and its type */
private type VarInfo = (NameTree, Tree)
+// ----- 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.
+ */
+ val References = new Attachment.Key[List[Tree]]
+
+ /** Attachment key for TypeTrees marked with TypeRefOfSym or InfoOfSym
+ * which contains the symbol of the original tree from which this
+ * TypeTree is derived.
+ */
+ 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.
+ */
+ def refTypeTree(original: Tree, marker: TypeTree): TypeTree = {
+ val result = TypeTree(marker)
+ val existing = original.attachmentOrElse(References, Nil)
+ original.putAttachment(References, result :: existing)
+ result
+ }
+
+// ----- Desugar methods -------------------------------------------------
+
/** var x: Int = expr
* ==>
* def x: Int = expr
@@ -35,7 +73,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 = TypeTree())
+ val setterParam = makeSyntheticParameter(tpt = refTypeTree(vdef, InfoOfSym))
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/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 39da1dbae..ea396519a 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -84,7 +84,7 @@ trait Checking extends NoChecking {
/** Check that (return) type of implicit definition is not empty */
override def checkImplicitTptNonEmpty(defTree: untpd.ValOrDefDef)(implicit ctx: Context): Unit = defTree.tpt match {
- case TypeTree(original) if original.isEmpty =>
+ case TypeTree(untpd.EmptyTree) =>
val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else ""
ctx.error(i"${resStr}type of implicit definition needs to be given explicitly", defTree.pos)
case _ =>
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index c318ddf36..21b87aee4 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -173,6 +173,11 @@ class Namer { typer: Typer =>
enclosingClassNamed(mods.privateWithin, mods.pos)
def record(sym: Symbol): Symbol = {
+ val refs = tree.attachmentOrElse(desugar.References, Nil)
+ if (refs.nonEmpty) {
+ tree.removeAttachment(desugar.References)
+ refs foreach (_.pushAttachment(desugar.OriginalSymbol, sym))
+ }
tree.pushAttachment(SymOfTree, sym)
sym
}
@@ -516,10 +521,7 @@ class Namer { typer: Typer =>
* NoType if neither case holds.
*/
val inherited =
- if ((sym is Param) && sym.owner.isSetter) // fill in type from getter result type
- defContext(sym.owner)
- .denotNamed(sym.owner.asTerm.name.setterToGetter).info.widenExpr
- else if (sym.owner.isTerm) NoType
+ if (sym.owner.isTerm) NoType
else {
// TODO: Look only at member of supertype instead?
lazy val schema = paramFn(WildcardType)
@@ -578,7 +580,7 @@ class Namer { typer: Typer =>
val rhsCtx = ctx.fresh addMode Mode.InferringReturnType
def rhsType = typedAheadExpr(mdef.rhs, rhsProto)(rhsCtx).tpe.widen.approximateUnion
def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos)
- inherited orElse lhsType
+ inherited orElse lhsType orElse WildcardType
}
paramFn(typedAheadType(mdef.tpt, pt).tpe)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index f961a4544..32e847757 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -635,11 +635,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") {
- val original1 = typed(tree.original)
- val ownType =
- if (original1.isEmpty) { assert(isFullyDefined(pt, ForceDegree.none)); pt }
- else original1.tpe
- cpy.TypeTree(tree, original1) withType ownType
+ 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 =>
+ assert(isFullyDefined(pt, ForceDegree.none))
+ pt
+ case desugar.TypeRefOfSym =>
+ symbol.typeRef
+ case desugar.InfoOfSym =>
+ symbol.info.resultType
+ }
+ cpy.TypeTree(tree, untpd.EmptyTree).withType(ownType)
+ }
+ else {
+ val original1 = typed(tree.original)
+ cpy.TypeTree(tree, original1).withType(original1.tpe)
+ }
}
def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") {