Skip to content

Commit b8a7aa0

Browse files
committed
constant-typed final val in trait should yield impl method
1 parent 1655d1b commit b8a7aa0

File tree

4 files changed

+14
-9
lines changed

4 files changed

+14
-9
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
5858
def needsImplMethod(sym: Symbol) = (
5959
sym.isMethod
6060
&& isInterfaceMember(sym)
61-
&& (!sym.isAccessor || sym.isLazy) // We no longer do the implclass-dance for accessors -- they are mixed in directly into their implementing classes during the fields phase
61+
&& (!(sym hasFlag ACCESSOR) || sym.isLazy || !(sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS)) // SYNTHESIZE_IMPL_IN_SUBCLASS accessors are mixed in by the fields phase, but others should be treated as regulars methods (constant-typed getters)
6262
// so that constructors populates the init method in the impl class
6363
&& (!sym.hasFlag(DEFERRED | SUPERACCESSOR) || (sym hasFlag lateDEFERRED))
6464
)

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,19 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
138138

139139
// strict, memoized accessors will receive an implementation in first real class to extend this trait
140140
decls.foreach {
141-
case accessor if (accessor hasFlag ACCESSOR) && !(accessor hasFlag (DEFERRED | LAZY))
142-
&& fieldMemoizationIn(accessor, clazz).needsField =>
141+
case accessor if accessor hasFlag ACCESSOR =>
143142
// only affects private symbols, with a destructive update of their name, also sets flags
144143
// required for private vals in traits
145144
accessor.makeNotPrivate(clazz)
146145

147-
// in a trait, a memoized accessor becomes deferred
148-
// (it'll receive an implementation in the first real class to extend this trait)
149-
markAccessorImplementedInSubclass(accessor)
146+
if (!(accessor hasFlag (DEFERRED | LAZY)) && fieldMemoizationIn(accessor, clazz).needsField) {
147+
// in a trait, a memoized accessor becomes deferred
148+
// (it'll receive an implementation in the first real class to extend this trait)
149+
markAccessorImplementedInSubclass(accessor)
150150

151-
if ((accessor hasFlag STABLE) && accessor.isGetter) // TODO: isGetter is probably redundant?
152-
newSetters += newTraitSetter(accessor, clazz)
151+
if ((accessor hasFlag STABLE) && accessor.isGetter) // TODO: isGetter is probably redundant?
152+
newSetters += newTraitSetter(accessor, clazz)
153+
}
153154

154155
case _ =>
155156
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
4646
sym.owner.isImplClass
4747
&& sym.isMethod
4848
&& (!sym.isModule || sym.hasFlag(PRIVATE | LIFTED))
49-
&& (!(sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isLazy)
49+
&& (!(sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isLazy || !(sym hasFlag SYNTHESIZE_IMPL_IN_SUBCLASS))
5050
)
5151

5252
/** A member of a trait is static only if it belongs only to the

test/files/trait-defaults/fields.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
trait T { final val C = "S" }
2+
// there should be a C method in `T$class`!
3+
class C extends T { println(C) }
4+
15
trait T {
26
type Res
37
val x: Res = ???

0 commit comments

Comments
 (0)