aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-09-21 14:45:36 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-10-11 08:24:36 +0200
commitd288981f42cd8fde42340264a73d30e037bffec5 (patch)
treebd9371b9c000c06c1d830d8b3f04836da9979451 /src/dotty/tools
parentce81244e6c4fc7b5b8ccc70ad32290045a591739 (diff)
downloaddotty-d288981f42cd8fde42340264a73d30e037bffec5.tar.gz
dotty-d288981f42cd8fde42340264a73d30e037bffec5.tar.bz2
dotty-d288981f42cd8fde42340264a73d30e037bffec5.zip
Fix tree typing to account for trees after constructors is run.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala10
-rw-r--r--src/dotty/tools/dotc/typer/ReTyper.scala3
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala29
4 files changed, 25 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index ef5baca07..5412b66b8 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -46,7 +46,6 @@ class TreeChecker {
case _ =>
Nil
}
-
def check(phasesToRun: Seq[Phase], ctx: Context) = {
println(s"checking ${ctx.compilationUnit} after phase ${ctx.phase.prev}")
val checkingCtx = ctx.fresh
@@ -99,7 +98,8 @@ class TreeChecker {
private def checkOwner(tree: untpd.Tree)(implicit ctx: Context): Unit = {
def ownerMatches(symOwner: Symbol, ctxOwner: Symbol): Boolean =
symOwner == ctxOwner ||
- ctxOwner.isWeakOwner && ownerMatches(symOwner, ctxOwner.owner)
+ ctxOwner.isWeakOwner && !(ctxOwner is Method | Lazy | Mutable) &&
+ ownerMatches(symOwner, ctxOwner.owner)
if(!ownerMatches(tree.symbol.owner, ctx.owner)) {
assert(ownerMatches(tree.symbol.owner, ctx.owner),
i"bad owner; ${tree.symbol} has owner ${tree.symbol.owner}, expected was ${ctx.owner}\n" +
@@ -130,10 +130,10 @@ class TreeChecker {
super.typedStats(trees, exprOwner)
}
-
override def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = {
- if (ctx.mode.isExpr)
- if(!(tree.tpe <:< pt))
+ def isPrimaryConstructorReturn =
+ ctx.owner.isPrimaryConstructor && pt.isRef(ctx.owner.owner) && tree.tpe.isRef(defn.UnitClass)
+ if (ctx.mode.isExpr && !isPrimaryConstructorReturn)
assert(tree.tpe <:< pt,
s"error at ${sourcePos(tree.pos)}\n" +
err.typeMismatchStr(tree.tpe, pt))
diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala
index 31a776fc9..6895f9978 100644
--- a/src/dotty/tools/dotc/typer/ReTyper.scala
+++ b/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -71,6 +71,9 @@ class ReTyper extends Typer {
override def addTypedModifiersAnnotations(mods: untpd.Modifiers, sym: Symbol)(implicit ctx: Context): Modifiers =
typedModifiers(mods, sym)
+ override def ensureConstrCall(cls: ClassSymbol, parents: List[Tree])(implicit ctx: Context): List[Tree] =
+ parents
+
override def encodeName(tree: untpd.NameTree)(implicit ctx: Context) = tree
override def handleUnexpectedFunType(tree: untpd.Apply, fun: Tree)(implicit ctx: Context): Tree = fun.tpe match {
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 5604a607c..79d86de06 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -235,7 +235,7 @@ trait TypeAssigner {
}
val owntype =
if (!mix.isEmpty) findMixinSuper(cls.info)
- else if (inConstrCall) cls.info.firstParent
+ else if (inConstrCall || ctx.erasedTypes) cls.info.firstParent
else {
val ps = cls.info.parents
if (ps.isEmpty) defn.AnyType else ps.reduceLeft((x: Type, y: Type) => x & y)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index ebd33a6ff..46fd17d15 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -374,8 +374,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case lhs =>
val lhsCore = typedUnadapted(lhs)
def lhs1 = typed(untpd.TypedSplice(lhsCore))
+ def canAssign(sym: Symbol) = // allow assignments from the primary constructor to class fields
+ sym.is(Mutable, butNot = Accessor) ||
+ ctx.owner.isPrimaryConstructor && !sym.is(Method) && sym.owner == ctx.owner.owner
lhsCore.tpe match {
- case ref: TermRef if ref.symbol is (Mutable, butNot = Accessor) =>
+ case ref: TermRef if canAssign(ref.symbol) =>
assignType(cpy.Assign(tree)(lhs1, typed(tree.rhs, ref.info)))
case _ =>
def reassignmentToVal =
@@ -843,20 +846,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
result
}
- /** If this is a real class, make sure its first parent is a
- * constructor call. Cannot simply use a type.
- */
- def ensureConstrCall(parents: List[Tree]): List[Tree] = {
- val firstParent :: otherParents = parents
- if (firstParent.isType && !(cls is Trait))
- typed(untpd.New(untpd.TypedSplice(firstParent), Nil))(superCtx) :: otherParents
- else parents
- }
-
val mods1 = addTypedModifiersAnnotations(mods, cls)
val constr1 = typed(constr).asInstanceOf[DefDef]
- val parents1 = ensureConstrCall(ensureFirstIsClass(
- parents mapconserve typedParent, cdef.pos.toSynthetic))
+ val parentsWithClass = ensureFirstIsClass(parents mapconserve typedParent, cdef.pos.toSynthetic)
+ val parents1 = ensureConstrCall(cls, parentsWithClass)(superCtx)
val self1 = typed(self)(ctx.outer).asInstanceOf[ValDef] // outer context where class members are not visible
val dummy = localDummy(cls, impl)
val body1 = typedStats(body, dummy)(inClassContext(self1.symbol))
@@ -875,6 +868,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
// 4. Polymorphic type defs override nothing.
}
+ /** If this is a real class, make sure its first parent is a
+ * constructor call. Cannot simply use a type. Overridden in ReTyper.
+ */
+ def ensureConstrCall(cls: ClassSymbol, parents: List[Tree])(implicit ctx: Context): List[Tree] = {
+ val firstParent :: otherParents = parents
+ if (firstParent.isType && !(cls is Trait))
+ typed(untpd.New(untpd.TypedSplice(firstParent), Nil)) :: otherParents
+ else parents
+ }
+
/** Overridden in retyper */
def checkVariance(tree: Tree)(implicit ctx: Context) = VarianceChecker.check(tree)