summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala14
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala2
3 files changed, 13 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 2ccc44f234..74e6c58388 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -262,17 +262,17 @@ abstract class LambdaLift extends InfoTransform {
debuglog(s"new proxy ${proxyName} in ${owner.fullLocationString}")
val proxy =
if (owner.isTrait) {
- // TODO preserve pre-erasure info for the accessors?
- // TODO: do we need SYNTHESIZE_IMPL_IN_SUBCLASS to indicate that `notDeferred(setter)` should hold
val accessorFlags = newFlags.toLong | ACCESSOR | SYNTHESIZE_IMPL_IN_SUBCLASS
+
+ // TODO do we need to preserve pre-erasure info for the accessors (and a NullaryMethodType for the getter)?
+ // can't have a field in the trait, so add a setter
val setter = owner.newMethod(nme.expandedSetterName(proxyName.setterName, owner), fv.pos, accessorFlags)
- setter setInfo MethodType(setter.newSyntheticValueParams(List(fv.info)), UnitTpe)
- owner.info.decls enter setter
+ setter setInfoAndEnter MethodType(setter.newSyntheticValueParams(List(fv.info)), UnitTpe)
- val getter = owner.newMethod(proxyName.getterName, fv.pos, accessorFlags | STABLE)
- getter setInfo MethodType(Nil, fv.info)
+ // the getter serves as the proxy -- entered below
+ owner.newMethod(proxyName.getterName, fv.pos, accessorFlags | STABLE) setInfo MethodType(Nil, fv.info)
} else
- owner.newValue(proxyName.toTermName, owner.pos, newFlags.toLong | PrivateLocal) setInfo fv.info
+ owner.newValue(proxyName.toTermName, fv.pos, newFlags.toLong | PrivateLocal) setInfo fv.info
if (owner.isClass) owner.info.decls enter proxy
proxy
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index dae0deeccd..6c8904f5d0 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -25,8 +25,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
* (need to exclude lambdaLIFTED methods, as they do no exist during explicitouter and thus did not need to be excluded...)
*
* They may be protected, now that traits are compiled 1:1 to interfaces.
- * (The same disclaimers about mapping Scala's notion of visibility to Java's apply.)
+ * The same disclaimers about mapping Scala's notion of visibility to Java's apply:
+ * we cannot emit PROTECTED methods in interfaces on the JVM,
+ * but knowing that these trait methods are protected means we won't emit static forwarders.
*
+ * JVMLS: "Methods of interfaces may have any of the flags in Table 4.6-A set
+ * except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS ยง9.4)."
*
* TODO: can we just set the right flags from the start??
* could we use the final flag to indicate a private method is really-really-private?
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index c036a2a9b8..ea323d0fba 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -301,7 +301,7 @@ trait MethodSynthesis {
if (tree.symbol.owner.isTrait || Field.noFieldFor(tree)) rhs1 // TODO move tree.symbol.owner.isTrait into noFieldFor
else gen.mkAssignAndReturn(tree.symbol, rhs1)
- derivedSym setPos tree.pos // cannot set it at createAndEnterSymbol because basisSym can possibly still have NoPosition
+ derivedSym setPos tree.pos // TODO: can we propagate `tree.pos` to `derivedSym` when the symbol is created?
val ddefRes = DefDef(derivedSym, new ChangeOwnerTraverser(tree.symbol, derivedSym)(body))
// ValDef will have its position focused whereas DefDef will have original correct rangepos
// ideally positions would be correct at the creation time but lazy vals are really a special case