aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
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/dotc/typer/Typer.scala
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/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala29
1 files changed, 16 insertions, 13 deletions
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)