Skip to content

Commit

Permalink
can we retire lateDEFERRED?
Browse files Browse the repository at this point in the history
it seems redundant with SYNTHESIZE_IMPL_IN_SUBCLASS
  • Loading branch information
adriaanm committed May 5, 2016
1 parent 910bc52 commit 31868d3
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 29 deletions.
4 changes: 0 additions & 4 deletions src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,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.
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/scala/tools/nsc/transform/Fields.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor

// used for internal communication between info and tree transform of this phase -- not pickled, not in initialflags
// TODO: reuse MIXEDIN for NEEDS_TREES
override def phaseNewFlags: Long = NEEDS_TREES | OVERRIDDEN_TRAIT_SETTER | MIXEDIN_ACCESSOR // TODO: | lateDEFERRED ?
override def phaseNewFlags: Long = NEEDS_TREES | OVERRIDDEN_TRAIT_SETTER | MIXEDIN_ACCESSOR

private final val OVERRIDDEN_TRAIT_SETTER = TRANS_FLAG

Expand All @@ -84,7 +84,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
private def concreteOrSynthImpl(sym: Symbol): Boolean = !(sym hasFlag DEFERRED) || (sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS)

private def setTraitAccessorFlags(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)
Expand All @@ -94,7 +94,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 MIXEDIN_ACCESSOR | OVERRIDE | NEEDS_TREES resetFlag DEFERRED | lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS
cloneInSubclass setFlag MIXEDIN_ACCESSOR | OVERRIDE | NEEDS_TREES resetFlag DEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS

private def setFieldFlags(accessor: Symbol, fieldInSubclass: TermSymbol): Unit =
fieldInSubclass setFlag ( NEEDS_TREES |
Expand Down
30 changes: 15 additions & 15 deletions src/compiler/scala/tools/nsc/transform/Mixin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,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)
Expand Down Expand Up @@ -109,7 +109,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {

// --------- type transformation -----------------------------------------------

private def notDeferredOrLate(sym: Symbol) = !sym.hasFlag(DEFERRED) || sym.hasFlag(lateDEFERRED)
private def notDeferred(sym: Symbol) = !sym.hasFlag(DEFERRED) || sym.hasFlag(SYNTHESIZE_IMPL_IN_SUBCLASS)

/** Is member overridden (either directly or via a bridge) in base class sequence `bcs`? */
def isOverriddenAccessor(member: Symbol, bcs: List[Symbol]): Boolean = beforeOwnPhase {
Expand All @@ -118,7 +118,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
Expand Down Expand Up @@ -174,21 +174,24 @@ 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)
}

/* 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)
Expand Down Expand Up @@ -236,7 +239,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 */
Expand Down Expand Up @@ -311,9 +314,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.
Expand Down Expand Up @@ -917,9 +920,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?!?")

Expand Down
13 changes: 7 additions & 6 deletions src/reflect/scala/reflect/internal/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,14 @@ class Flags extends ModifierFlags {
//
// Flags from 1L to (1L << 50) are normal flags.
//
// The flags DEFERRED (1L << 4) to MODULE (1L << 8) have a `late` counterpart. Late flags change
// their counterpart from 0 to 1 after a specific phase (see below). The first late flag
// (lateDEFERRED) is at (1L << 51), i.e., late flags are shifted by 47. The last one is (1L << 55).
// The "late" counterpart to flags DEFERRED (1L << 4) to MODULE (1L << 8)
// show up in `sym.flags` as their regular counterpart once the phase mask admits them (see below).
// The first late flag (lateDEFERRED) is at (1L << 51), i.e., late flags are shifted by 47. The last one is (1L << 55).
// Think of it as a poor man's flag history akin to the type history for a symbol's info.
//
// The flags PROTECTED (1L) to PRIVATE (1L << 2) have a `not` counterpart. Negated flags change
// their counterpart from 1 to 0 after a specific phase (see below). They are shifted by 56, i.e.,
// the first negated flag (notPROTECTED) is at (1L << 56), the last at (1L << 58).
// The "not" counterpart to flags PROTECTED (1L) to PRIVATE (1L << 2)
// are negated flags that suppress their counterpart after a specific phase (see below).
// They are shifted by 56, i.e., the first negated flag (notPROTECTED) is at (1L << 56), the last at (1L << 58).
//
// Late and negative flags are only enabled after certain phases, implemented by the phaseNewFlags
// method of the SubComponent, so they implement a bit of a flag history.
Expand Down

0 comments on commit 31868d3

Please sign in to comment.