aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/src/dotty/tools/dotc/ast/TreeInfo.scala27
-rw-r--r--compiler/src/dotty/tools/dotc/core/Flags.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymDenotations.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala1
-rw-r--r--tests/pickling/innerclass.scala3
7 files changed, 22 insertions, 24 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
index dd890dc50..b00d7df71 100644
--- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -26,23 +26,6 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
case _ => false
}
- /** The largest subset of {NoInits, PureInterface} that a
- * trait enclosing this statement can have as flags.
- * Does tree contain an initialization part when seen as a member of a class or trait?
- */
- def defKind(tree: Tree): FlagSet = unsplice(tree) match {
- case EmptyTree | _: Import =>
- NoInitsInterface
- case tree: TypeDef =>
- if (tree.isClassDef) NoInits else NoInitsInterface
- case tree: DefDef =>
- if (tree.unforcedRhs == EmptyTree && tree.vparamss.forall(_.forall(_.unforcedRhs == EmptyTree))) NoInitsInterface else NoInits
- case tree: ValDef =>
- if (tree.unforcedRhs == EmptyTree) NoInitsInterface else EmptyFlags
- case _ =>
- EmptyFlags
- }
-
def isOpAssign(tree: Tree) = unsplice(tree) match {
case Apply(fn, _ :: _) =>
unsplice(fn) match {
@@ -588,6 +571,16 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
accum(Nil, root)
}
+ /** The largest subset of {NoInits, PureInterface} that a
+ * trait enclosing this statement can have as flags.
+ */
+ def defKind(tree: Tree): FlagSet = unsplice(tree) match {
+ case EmptyTree | _: Import => NoInitsInterface
+ case tree: TypeDef => if (tree.isClassDef) NoInits else NoInitsInterface
+ case tree: DefDef => if (tree.unforcedRhs == EmptyTree) NoInitsInterface else NoInits
+ case tree: ValDef => if (tree.unforcedRhs == EmptyTree) NoInitsInterface else EmptyFlags
+ case _ => EmptyFlags
+ }
/** The top level classes in this tree, including only those module classes that
* are not a linked class of some other class in the result.
diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala
index d2a1c58f5..c1267d8a2 100644
--- a/compiler/src/dotty/tools/dotc/core/Flags.scala
+++ b/compiler/src/dotty/tools/dotc/core/Flags.scala
@@ -287,9 +287,10 @@ object Flags {
/** A trait that has only abstract methods as members
- * (and therefore can be represented by a Java interface
+ * and therefore can be represented by a Java interface.
+ * Warning: flag is set during regular typer pass, should be tested only after typer.
*/
- final val PureInterface = typeFlag(22, "interface") // TODO when unpickling, reconstitute from context
+ final val PureInterface = typeFlag(22, "interface")
/** Labeled with of abstract & override */
final val AbsOverride = termFlag(22, "abstract override")
@@ -338,7 +339,9 @@ object Flags {
final val JavaStaticTerm = JavaStatic.toTermFlags
final val JavaStaticType = JavaStatic.toTypeFlags
- /** Trait does not have fields or initialization code */
+ /** Trait does not have fields or initialization code.
+ * Warning: flag is set during regular typer pass, should be tested only after typer.
+ */
final val NoInits = typeFlag(32, "<noInits>")
/** Variable is accessed from nested function. */
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
index 9b9caf8e7..c98b444d9 100644
--- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -158,7 +158,7 @@ object SymDenotations {
final def resetFlag(flags: FlagSet): Unit = { myFlags &~= flags }
/** Set applicable flags from `flags` which is a subset of {NoInits, PureInterface} */
- final def setApplicableFlags(flags: FlagSet): Unit = {
+ final def setNoInitsFlags(flags: FlagSet): Unit = {
val mask = if (myFlags.is(Trait)) NoInitsInterface else NoInits
setFlag(flags & mask)
}
diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
index fcba957c0..fdb8a97ae 100644
--- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
@@ -768,7 +768,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, posUnpickle
}
else EmptyValDef
setClsInfo(parentRefs, if (self.isEmpty) NoType else self.tpt.tpe)
- cls.setApplicableFlags(fork.indexStats(end))
+ cls.setNoInitsFlags(fork.indexStats(end))
val constr = readIndexedDef().asInstanceOf[DefDef]
def mergeTypeParamsAndAliases(tparams: List[TypeDef], stats: List[Tree])(implicit ctx: Context): (List[Tree], List[Tree]) =
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 96660f15c..83ae8ad9f 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -818,8 +818,6 @@ class Namer { typer: Typer =>
Checking.checkWellFormed(cls)
if (isDerivedValueClass(cls)) cls.setFlag(Final)
- cls.setApplicableFlags(
- (NoInitsInterface /: impl.body)((fs, stat) => fs & defKind(stat)))
cls.info = avoidPrivateLeaks(cls, cls.pos)
}
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index b2e9d639d..ba14b7498 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1314,6 +1314,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val self1 = typed(self)(ctx.outer).asInstanceOf[ValDef] // outer context where class members are not visible
val dummy = localDummy(cls, impl)
val body1 = typedStats(impl.body, dummy)(inClassContext(self1.symbol))
+ cls.setNoInitsFlags((NoInitsInterface /: body1)((fs, stat) => fs & defKind(stat)))
// Expand comments and type usecases
cookComments(body1.map(_.symbol), self1.symbol)(localContext(cdef, cls).setNewScope)
diff --git a/tests/pickling/innerclass.scala b/tests/pickling/innerclass.scala
new file mode 100644
index 000000000..5881cf6ed
--- /dev/null
+++ b/tests/pickling/innerclass.scala
@@ -0,0 +1,3 @@
+trait Foo {
+ class Inner(x: Int = 42)
+}