Skip to content

Commit 892e13c

Browse files
committed
detect trait vals
see neg/delayed-init-ref.scala and neg/t562.scala
1 parent 536b978 commit 892e13c

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/compiler/scala/tools/nsc/transform/Fields.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
6868
else if (correspondingGetter.isEffectivelyFinal) cloneInSubclass setFlag FINAL
6969
}
7070

71-
private def setClonedAccessorFlags(orig: Symbol, cloneInSubclass: Symbol): Unit =
71+
// TODO: add MIXEDIN (see e.g., `accessed` on `Symbol`)
72+
private def setMixedinAccessorFlags(orig: Symbol, cloneInSubclass: Symbol): Unit =
7273
cloneInSubclass setFlag NEEDS_TREES resetFlag DEFERRED | lateDEFERRED | SYNTHESIZE_IMPL_IN_SUBCLASS
7374

7475
private def setFieldFlags(accessor: Symbol, fieldInSubclass: TermSymbol): Unit =
@@ -258,7 +259,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
258259
val mixedInAccessorAndFields = accessorsMaybeNeedingImpl map { accessor =>
259260
def cloneAccessor() = {
260261
val clonedAccessor = (accessor cloneSymbol clazz) setPos clazz.pos
261-
setClonedAccessorFlags(accessor, clonedAccessor)
262+
setMixedinAccessorFlags(accessor, clonedAccessor)
262263

263264
// if we don't cloneInfo, method argument symbols are shared between trait and subclasses --> lambalift proxy crash
264265
// TODO: use derive symbol variant?

src/reflect/scala/reflect/internal/Symbols.scala

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
9696
def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM)
9797
def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT)
9898
def isJava: Boolean = isJavaDefined
99-
def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable
100-
def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable
99+
100+
def isField: Boolean = isTerm && !isModule && (!isMethod || owner.isTrait && isAccessor)
101+
def isVal: Boolean = isField && !isMutable
102+
def isVar: Boolean = isField && !isLazy && isMutable
103+
101104
def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType
102105
def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL)
103106
def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL)
@@ -2057,7 +2060,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
20572060
assert(hasAccessorFlag, this)
20582061
val localField = owner.info decl localName
20592062

2060-
if (localField == NoSymbol && this.hasFlag(MIXEDIN)) {
2063+
if (localField == NoSymbol && this.hasFlag(MIXEDIN)) { // TODO: fields phase does not (yet?) add MIXEDIN in setMixedinAccessorFlags
20612064
// SI-8087: private[this] fields don't have a `localName`. When searching the accessed field
20622065
// for a mixin accessor of such a field, we need to look for `name` instead.
20632066
// The phase travel ensures that the field is found (`owner` is the trait class symbol, the
@@ -2103,8 +2106,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
21032106
/** If this is a lazy value, the lazy accessor; otherwise this symbol. */
21042107
def lazyAccessorOrSelf: Symbol = if (isLazy) lazyAccessor else this
21052108

2106-
/** If this is an accessor, the accessed symbol. Otherwise, this symbol. */
2107-
def accessedOrSelf: Symbol = if (hasAccessorFlag) accessed else this
2109+
/** `accessed`, if this is an accessor that should have an underlying field. Otherwise, `this`.
2110+
* Note that a "regular" accessor in a trait does not have a field, as an interface cannot define a field.
2111+
* "non-regular" vals are: early initialized or lazy vals.
2112+
* Eventually, we should delay introducing symbols for all val/vars until the fields (or lazyvals) phase,
2113+
* as they are an implementation detail that's irrelevant to type checking.
2114+
*/
2115+
def accessedOrSelf: Symbol =
2116+
if (hasAccessorFlag && (!owner.isTrait || hasFlag(PRESUPER | LAZY))) accessed
2117+
else this
21082118

21092119
/** For an outer accessor: The class from which the outer originates.
21102120
* For all other symbols: NoSymbol

0 commit comments

Comments
 (0)