diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-05-04 18:22:34 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan@lightbend.com> | 2016-08-11 10:59:15 -0700 |
commit | 6f0bb49c17ea1a46283777e39ed5ce016aa048a5 (patch) | |
tree | b39d9328148dee9e53e4eb6ae3ac62f3ffd54f32 /src/compiler | |
parent | 6858134fb01315c13df05fbef1b310443f3dac95 (diff) | |
download | scala-6f0bb49c17ea1a46283777e39ed5ce016aa048a5.tar.gz scala-6f0bb49c17ea1a46283777e39ed5ce016aa048a5.tar.bz2 scala-6f0bb49c17ea1a46283777e39ed5ce016aa048a5.zip |
Reduce flag fiddling
There isn't much point to the late* flags in a world where
we're mutating flags left and right in tree and info transformers...
So, lets get rid of the indirection until we can include flags
in a symbol's type history, like we do for its info.
This retires lateDEFERRED (redundant with SYNTHESIZE_IMPL_IN_SUBCLASS).
Since it's introduced so late, it makes little sense to have these
synthetic members go back to DEFERRED. Instead, just set DEFERRED directly.
Also remove unused late* and not* flags.
notPRIVATE subsumes lateFINAL for effective finality (scala/scala-dev#126)
Diffstat (limited to 'src/compiler')
8 files changed, 26 insertions, 36 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index 27a4cbd134..e1decaba3e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -239,6 +239,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { sym.isErroneous } + /* * must-single-thread */ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index 836893a98b..b2a575d7d1 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -12,6 +12,7 @@ import scala.tools.nsc.backend.jvm.opt._ import scala.tools.nsc.backend.jvm.BTypes._ import BackendReporting._ import scala.tools.nsc.settings.ScalaSettings +import scala.reflect.internal.Flags.{DEFERRED, SYNTHESIZE_IMPL_IN_SUBCLASS} /** * This class mainly contains the method classBTypeFromSymbol, which extracts the necessary @@ -580,7 +581,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { // // However, due to https://github.com/scala/scala-dev/issues/126, this currently does not // work, the abstract accessor for O will be marked effectivelyFinal. - val effectivelyFinal = methodSym.isEffectivelyFinalOrNotOverridden && !methodSym.isDeferred + val effectivelyFinal = methodSym.isEffectivelyFinalOrNotOverridden && !(methodSym hasFlag DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS) val info = MethodInlineInfo( effectivelyFinal = effectivelyFinal, @@ -716,15 +717,9 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { // scala compiler. The word final is heavily overloaded unfortunately; // for us it means "not overridable". At present you can't override // vars regardless; this may change. - // - // The logic does not check .isFinal (which checks flags for the FINAL flag, - // and includes symbols marked lateFINAL) instead inspecting rawflags so - // we can exclude lateFINAL. Such symbols are eligible for inlining, but to - // avoid breaking proxy software which depends on subclassing, we do not - // emit ACC_FINAL. val finalFlag = ( - (((sym.rawflags & symtab.Flags.FINAL) != 0) || isTopLevelModuleClass(sym)) + (sym.isFinal || isTopLevelModuleClass(sym)) && !sym.enclClass.isTrait && !sym.isClassConstructor && (!sym.isMutable || nme.isTraitSetterName(sym.name)) // lazy vals and vars and their setters cannot be final, but trait setters are diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 104e2e8c93..406832c262 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -13,10 +13,6 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => import global._ // the global environment import definitions._ // standard classes and methods - /** lateDEFERRED for formerly concrete methods in such traits. - */ - override def phaseNewFlags: Long = lateDEFERRED - def transformMixinInfo(tp: Type): Type = tp match { case ClassInfoType(parents, decls, clazz) if clazz.isPackageClass || !clazz.isJavaDefined => diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index dc62b40578..f3fd7c5f67 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -504,7 +504,7 @@ abstract class Erasure extends AddInterfaces if (!bridgeNeeded) return - var newFlags = (member.flags | BRIDGE | ARTIFACT) & ~(ACCESSOR | DEFERRED | LAZY | lateDEFERRED) + var newFlags = (member.flags | BRIDGE | ARTIFACT) & ~(ACCESSOR | DEFERRED | LAZY) // If `member` is a ModuleSymbol, the bridge should not also be a ModuleSymbol. Otherwise we // end up with two module symbols with the same name in the same scope, which is surprising // when implementing later phases. diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala index 105bf0410d..a9ed8e3aca 100644 --- a/src/compiler/scala/tools/nsc/transform/Fields.scala +++ b/src/compiler/scala/tools/nsc/transform/Fields.scala @@ -83,10 +83,10 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor private def accessorImplementedInSubclass(accessor: Symbol) = (accessor hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS) && (accessor hasFlag (ACCESSOR | MODULE)) - private def concreteOrSynthImpl(sym: Symbol): Boolean = !(sym hasFlag DEFERRED) || (sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS) + @inline final def notDeferredOrSynthImpl(sym: Symbol): Boolean = !(sym hasFlag DEFERRED) || (sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS) private def synthesizeImplInSubclasses(accessor: Symbol): Unit = - accessor setFlag lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS + accessor setFlag SYNTHESIZE_IMPL_IN_SUBCLASS private def setClonedTraitSetterFlags(clazz: Symbol, correspondingGetter: Symbol, cloneInSubclass: Symbol): Unit = { val overridden = isOverriddenAccessor(correspondingGetter, clazz) @@ -96,7 +96,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor // TODO: add MIXEDIN (see e.g., `accessed` on `Symbol`) private def setMixedinAccessorFlags(orig: Symbol, cloneInSubclass: Symbol): Unit = - cloneInSubclass setFlag OVERRIDE | NEEDS_TREES resetFlag DEFERRED | lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS + cloneInSubclass setFlag OVERRIDE | NEEDS_TREES resetFlag DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS private def setFieldFlags(accessor: Symbol, fieldInSubclass: TermSymbol): Unit = fieldInSubclass setFlag (NEEDS_TREES | @@ -128,7 +128,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor def matchingAccessor(pre: Type, member: Symbol, clazz: Symbol) = { - val res = member.matchingSymbol(clazz, pre) filter (sym => (sym hasFlag ACCESSOR) && concreteOrSynthImpl(sym)) + val res = member.matchingSymbol(clazz, pre) filter (sym => (sym hasFlag ACCESSOR) && notDeferredOrSynthImpl(sym)) // if (res != NoSymbol) println(s"matching accessor for $member in $clazz = $res (under $pre)") // else println(s"no matching accessor for $member in $clazz (under $pre) among ${clazz.info.decls}") res diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index 0db9f19597..29ba21cba7 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -76,7 +76,7 @@ abstract class Flatten extends InfoTransform { decls1 enter sym if (sym.isModule) { // In theory, we could assert(sym.isMethod), because nested, non-static modules are - // transformed to methods (lateMETHOD flag added in RefChecks). But this requires + // transformed to methods (METHOD flag added in UnCurry). But this requires // forcing sym.info (see comment on isModuleNotMethod), which forces stub symbols // too eagerly (SI-8907). diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 0033736dbe..441ae625d0 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -19,8 +19,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { /** The name of the phase: */ val phaseName: String = "mixin" - /** The phase might set the following new flags: */ - override def phaseNewFlags: Long = lateMODULE | notOVERRIDE /** This map contains a binding (class -> info) if * the class with this info at phase mixinPhase has been treated for mixin composition @@ -46,7 +44,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { */ private def isImplementedStatically(sym: Symbol) = ( sym.isMethod - && notDeferredOrLate(sym) + && notDeferred(sym) && sym.owner.isTrait && (!sym.isModule || sym.hasFlag(PRIVATE | LIFTED)) && (!(sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isLazy) @@ -109,7 +107,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { // --------- type transformation ----------------------------------------------- - private def notDeferredOrLate(sym: Symbol) = !sym.hasFlag(DEFERRED) || sym.hasFlag(lateDEFERRED) + @inline final def notDeferred(sym: Symbol) = fields.notDeferredOrSynthImpl(sym) /** Is member overridden (either directly or via a bridge) in base class sequence `bcs`? */ def isOverriddenAccessor(member: Symbol, bcs: List[Symbol]): Boolean = beforeOwnPhase { @@ -118,7 +116,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { sym => sym.hasFlag(ACCESSOR) && !sym.hasFlag(MIXEDIN) && - notDeferredOrLate(sym) && + notDeferred(sym) && matchesType(sym.tpe, member.tpe, alwaysMatchSimple = true)) } ( bcs.head != member.owner @@ -178,11 +176,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { treatedClassInfos(clazz) = clazz.info assert(phase == currentRun.mixinPhase, phase) - /* Create a new getter. Getters are never private or local. They are - * always accessors and deferred. */ + /* Create a new getter. Getters are never private or local. + * They are always accessors and deferred. + * + * TODO: I guess newGetter and newSetter are needed for fields added after the fields phase (lambdalift) -- can we fix that? + */ def newGetter(field: Symbol): Symbol = { - // println("creating new getter for "+ field +" : "+ field.info +" at "+ field.locationString+(field hasFlag MUTABLE)) - val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED | ( if (field.isMutable) 0 else STABLE ) + //println(s"creating new getter for $field : ${field.info} at ${field.locationString} // mutable: ${field hasFlag MUTABLE}") + val newFlags = field.flags & ~PrivateLocal | ACCESSOR | ( if (field.isMutable) 0 else STABLE ) | SYNTHESIZE_IMPL_IN_SUBCLASS // TODO: do we need SYNTHESIZE_IMPL_IN_SUBCLASS to indicate that `notDeferred(setter)` should hold // TODO preserve pre-erasure info? clazz.newMethod(field.getterName, field.pos, newFlags) setInfo MethodType(Nil, field.info) } @@ -190,9 +191,9 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { /* Create a new setter. Setters are never private or local. They are * always accessors and deferred. */ def newSetter(field: Symbol): Symbol = { - //println("creating new setter for "+field+field.locationString+(field hasFlag MUTABLE)) + //println(s"creating new setter for $field ${field.locationString} // mutable: ${field hasFlag MUTABLE}") val setterName = field.setterName - val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED + val newFlags = field.flags & ~PrivateLocal | ACCESSOR | SYNTHESIZE_IMPL_IN_SUBCLASS // TODO: do we need SYNTHESIZE_IMPL_IN_SUBCLASS to indicate that `notDeferred(setter)` should hold val setter = clazz.newMethod(setterName, field.pos, newFlags) // TODO preserve pre-erasure info? setter setInfo MethodType(setter.newSyntheticValueParams(List(field.info)), UnitTpe) @@ -240,7 +241,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { def cloneAndAddMixinMember(mixinClass: Symbol, mixinMember: Symbol): Symbol = ( cloneAndAddMember(mixinClass, mixinMember, clazz) setPos clazz.pos - resetFlag DEFERRED | lateDEFERRED + resetFlag DEFERRED ) /* Mix in members of implementation class mixinClass into class clazz */ @@ -319,9 +320,9 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { } else if (mixinMember.hasAllFlags(METHOD | MODULE) && mixinMember.hasNoFlags(LIFTED | BRIDGE)) { // mixin objects: todo what happens with abstract objects? - // addMember(clazz, mixinMember.cloneSymbol(clazz, mixinMember.flags & ~(DEFERRED | lateDEFERRED)) setPos clazz.pos) + // addMember(clazz, mixinMember.cloneSymbol(clazz, mixinMember.flags & ~DEFERRED) setPos clazz.pos) } - else if (mixinMember.hasFlag(ACCESSOR) && notDeferredOrLate(mixinMember) + else if (mixinMember.hasFlag(ACCESSOR) && notDeferred(mixinMember) && (mixinMember hasFlag (LAZY | PARAMACCESSOR)) && !isOverriddenAccessor(mixinMember, clazz.info.baseClasses)) { // pick up where `fields` left off -- it already mixed in fields and accessors for regular vals. @@ -925,9 +926,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { addDefDef(sym) } else { // if class is not a trait add accessor definitions - // used to include `sym` with `sym hasFlag lateDEFERRED` as not deferred, - // but I don't think MIXEDIN members ever get this flag - assert(!sym.hasFlag(lateDEFERRED), s"mixedin $sym from $clazz has lateDEFERRED flag?!") if (sym.hasFlag(ACCESSOR) && !sym.hasFlag(DEFERRED)) { assert(sym hasFlag (LAZY | PARAMACCESSOR), s"mixed in $sym from $clazz is not lazy/param?!?") diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 40ab8c0cf8..87c14eb3a1 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -59,7 +59,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val phaseName: String = "specialize" /** The following flags may be set by this phase: */ - override def phaseNewFlags: Long = notPRIVATE | lateFINAL + override def phaseNewFlags: Long = notPRIVATE /** This phase changes base classes. */ override def changesBaseClasses = true |