diff options
Diffstat (limited to 'compiler/src/dotty')
6 files changed, 19 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) |