diff --git a/.gitignore b/.gitignore
index d6571a377f9..2ce4ed59f4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,7 @@
/src/intellij*/*.iml
/src/intellij*/*.ipr
/src/intellij*/*.iws
+/src/intellij*/.idea
**/.cache
/.idea
/.settings
diff --git a/build.xml b/build.xml
index 2e598f6f907..71077c570db 100755
--- a/build.xml
+++ b/build.xml
@@ -183,7 +183,7 @@ TODO:
-
+
@@ -763,6 +763,7 @@ TODO:
+
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 6be1fda1b51..eef9eca2af3 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -52,7 +52,7 @@ trait CompilationUnits { global: Global =>
* To get their sourcefiles, you need to dereference with .sourcefile
*/
private[this] val _depends = mutable.HashSet[Symbol]()
- // SBT compatibility (SI-6875)
+ // SBT compatibility -- pre-name-hashing dependency tracking for incremental compilation in sbt (SI-6875)
//
// imagine we have a file named A.scala, which defines a trait named Foo and a module named Main
// Main contains a call to a macro, which calls compileLate to define a mock for Foo
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index 64146585e58..c0e0240210d 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -9,6 +9,7 @@ package backend
package icode
import scala.collection.{ mutable, immutable }
+import scala.reflect.internal.Flags
import scala.reflect.internal.util.{ SourceFile, NoSourceFile }
trait ReferenceEquality {
@@ -217,7 +218,7 @@ trait Members {
/** Is this method deferred ('abstract' in Java sense)?
*/
- def isAbstractMethod = symbol.isDeferred || symbol.owner.isInterface || native
+ def isAbstractMethod = symbol.isDeferred || (symbol.owner.isInterface && !symbol.hasFlag(Flags.JAVA_DEFAULTMETHOD)) || native
def isStatic: Boolean = symbol.isStaticMember
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
index 93f5159f892..83c772403bd 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
@@ -429,17 +429,17 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
// impl class after mixin. So the filter in mixin is not exactly what we need here (we
// want to identify concrete trait methods, not any accessors). So we check some symbol
// properties manually.
- val traitMethodWithStaticImplementation = {
- import symtab.Flags._
- classSym.isTrait && !classSym.isImplClass &&
- erasure.needsImplMethod(methodSym) &&
- !methodSym.isModule &&
- !(methodSym hasFlag (ACCESSOR | SUPERACCESSOR))
- }
+// val traitMethodWithStaticImplementation = {
+// import symtab.Flags._
+// classSym.isTrait && !classSym.isImplClass &&
+// erasure.needsImplMethod(methodSym) &&
+// !methodSym.isModule &&
+// !(methodSym hasFlag (ACCESSOR | SUPERACCESSOR))
+// }
val info = MethodInlineInfo(
effectivelyFinal = effectivelyFinal,
- traitMethodWithStaticImplementation = traitMethodWithStaticImplementation,
+ traitMethodWithStaticImplementation = false, //traitMethodWithStaticImplementation,
annotatedInline = methodSym.hasAnnotation(ScalaInlineClass),
annotatedNoInline = methodSym.hasAnnotation(ScalaNoInlineClass)
)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 22ac8f84d4c..0e0d4dbc566 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -635,7 +635,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
case Apply(fun, args) if app.hasAttachment[delambdafy.LambdaMetaFactoryCapable] =>
val attachment = app.attachments.get[delambdafy.LambdaMetaFactoryCapable].get
genLoadArguments(args, paramTKs(app))
- genInvokeDynamicLambda(attachment.target, attachment.arity, attachment.functionalInterface)
+ genInvokeDynamicLambda(attachment.target, attachment.arity, attachment.functionalInterface, attachment.samMethod)
generatedType = asmMethodType(fun.symbol).returnType
case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) =>
@@ -1007,6 +1007,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def needsInterfaceCall(sym: Symbol) = (
sym.isInterface
+ || sym.isTrait
|| sym.isJavaDefined && sym.isNonBottomSubClass(definitions.ClassfileAnnotationClass)
)
@@ -1284,7 +1285,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def genSynchronized(tree: Apply, expectedType: BType): BType
def genLoadTry(tree: Try): BType
- def genInvokeDynamicLambda(lambdaTarget: Symbol, arity: Int, functionalInterface: Symbol) {
+ def genInvokeDynamicLambda(lambdaTarget: Symbol, arity: Int, functionalInterface: Symbol, samMethod: Symbol) {
val isStaticMethod = lambdaTarget.hasFlag(Flags.STATIC)
def asmType(sym: Symbol) = classBTypeFromSymbol(sym).toASMType
@@ -1299,9 +1300,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val invokedType = asm.Type.getMethodDescriptor(asmType(functionalInterface), (receiver ::: capturedParams).map(sym => toTypeKind(sym.info).toASMType): _*)
val constrainedType = new MethodBType(lambdaParams.map(p => toTypeKind(p.tpe)), toTypeKind(lambdaTarget.tpe.resultType)).toASMType
- val sam = functionalInterface.info.decls.find(_.isDeferred).getOrElse(functionalInterface.info.member(nme.apply))
- val samName = sam.name.toString
- val samMethodType = asmMethodType(sam).toASMType
+ val samName = samMethod.name.toString
+ val samMethodType = asmMethodType(samMethod).toASMType
val flags = 3 // TODO 2.12.x Replace with LambdaMetafactory.FLAG_SERIALIZABLE | LambdaMetafactory.FLAG_MARKERS
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
index a9b6a312e9c..df4a7152455 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
@@ -587,10 +587,10 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
}
val isNative = methSymbol.hasAnnotation(definitions.NativeAttr)
- val isAbstractMethod = (methSymbol.isDeferred || methSymbol.owner.isInterface)
+ val isAbstractMethod = (methSymbol.isDeferred || methSymbol.owner.isInterface) && !methSymbol.hasFlag(Flags.JAVA_DEFAULTMETHOD)
val flags = GenBCode.mkFlags(
javaFlags(methSymbol),
- if (claszSymbol.isInterface) asm.Opcodes.ACC_ABSTRACT else 0,
+ if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0,
if (methSymbol.isStrictFP) asm.Opcodes.ACC_STRICT else 0,
if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes
)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 8720da84e8c..55cde4ef3de 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -824,7 +824,7 @@ abstract class BTypes {
def info_=(i: Either[NoClassBTypeInfo, ClassInfo]): Unit = {
assert(_info == null, s"Cannot set ClassBType.info multiple times: $this")
_info = i
- checkInfoConsistency()
+ // checkInfoConsistency()
}
classBTypeFromInternalName(internalName) = this
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index 45d9cc3ff36..6fc237fceb2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -571,13 +571,13 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
import asm.Opcodes._
GenBCode.mkFlags(
if (privateFlag) ACC_PRIVATE else ACC_PUBLIC,
- if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0,
- if (sym.isInterface) ACC_INTERFACE else 0,
+ if ((sym.isDeferred && !sym.hasFlag(symtab.Flags.JAVA_DEFAULTMETHOD))|| sym.hasAbstractFlag) ACC_ABSTRACT else 0,
+ if (sym.isInterface || sym.isTrait) ACC_INTERFACE else 0,
if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0,
if (sym.isStaticMember) ACC_STATIC else 0,
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
if (sym.isArtifact) ACC_SYNTHETIC else 0,
- if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
+ if (sym.isClass && !sym.isTrait) ACC_SUPER else 0,
if (sym.hasJavaEnumFlag) ACC_ENUM else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(symtab.Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0,
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 7153c09377c..1c3154f1e9b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -306,7 +306,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
if (sym.isStaticMember) ACC_STATIC else 0,
if (sym.isBridge) ACC_BRIDGE | ACC_SYNTHETIC else 0,
if (sym.isArtifact) ACC_SYNTHETIC else 0,
- if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
+ if (sym.isClass && !sym.isTrait) ACC_SUPER else 0,
if (sym.hasJavaEnumFlag) ACC_ENUM else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0,
if (sym.hasFlag(Flags.SYNCHRONIZED)) ACC_SYNCHRONIZED else 0
@@ -1395,10 +1395,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
var resTpe: asm.Type = javaType(m.symbol.tpe.resultType)
if (m.symbol.isClassConstructor)
resTpe = asm.Type.VOID_TYPE
+ val isAbstractTraitMeth = isJInterface && !m.symbol.hasFlag(Flags.JAVA_DEFAULTMETHOD)
val flags = mkFlags(
javaFlags(m.symbol),
- if (isJInterface) asm.Opcodes.ACC_ABSTRACT else 0,
+ if (isAbstractTraitMeth) asm.Opcodes.ACC_ABSTRACT else 0,
if (m.symbol.isStrictFP) asm.Opcodes.ACC_STRICT else 0,
if (method.native) asm.Opcodes.ACC_NATIVE else 0, // native methods of objects are generated in mirror classes
if(isDeprecated(m.symbol)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo access flag
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 79776485def..445b54775ce 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -113,6 +113,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
/** Return the implementation class of a trait; create a new one of one does not yet exist */
def implClass(iface: Symbol): Symbol = {
+ assert(iface.needsImplClass)
iface.info
implClassMap.getOrElse(iface, enteringPhase(implClassPhase) {
@@ -311,7 +312,7 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
}
val mixinConstructorCalls: List[Tree] = {
for (mc <- clazz.mixinClasses.reverse
- if mc.hasFlag(lateINTERFACE))
+ if mc.hasFlag(lateINTERFACE)) // implies mc.needsImplClass
yield mixinConstructorCall(implClass(mc))
}
tree match {
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 6ecdd2b195d..1fa2888a587 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -13,6 +13,13 @@ import symtab.Flags._
/** This phase converts classes with parameters into Java-like classes with
* fields, which are assigned to from constructors.
+ *
+ * TODO: traits
+ * - drop field definitions,
+ * - introduce trait field setters to abstract over them in the init method
+ *
+ * mixins will add back fields and implementations for the setters to
+ * the classes that immediately extend the given trait
*/
abstract class Constructors extends Statics with Transform with ast.TreeDSL {
import global._
@@ -21,6 +28,12 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
/** the following two members override abstract members in Transform */
val phaseName: String = "constructors"
+ // using lateDEFERRED for notDEFERRED for my WIP
+ // (a lateDEFERRED trait member should not be considered deferred during refchecks,
+ // as it's automatically implemented in any class inheriting the trait,
+ // but it should be abstract in bytecode)
+ override def phaseNewFlags: Long = lateDEFERRED
+
protected def newTransformer(unit: CompilationUnit): Transformer =
new ConstructorTransformer(unit)
@@ -208,7 +221,10 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
detectUsages walk auxConstructorBuf
}
}
- def mustBeKept(sym: Symbol) = !omittables(sym)
+ def mustBeKept(sym: Symbol) = !omittable(sym)
+ // omit unused outers and non-memoized fields (I think we're no longer creating symbols for fields in traits, but still including backstop for now)
+ def omittable(sym: Symbol) = (omittables(sym) ||
+ (sym.isValue && !sym.isMethod && (!mustMemoize(sym) || sym.owner.isTrait))) // TODO: assert(!sym.owner.isTrait, sym.ownerChain)
} // OmittablesHelper
@@ -545,7 +561,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
// outer accessors become references to $outer parameter
if (canBeSupplanted(tree.symbol))
gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos
- else if (tree.symbol.outerSource == clazz && !clazz.isImplClass)
+ else if (tree.symbol.outerSource == clazz && !clazz.isTrait) // TODO was !clazz.isImplClass
gen.mkAttributedIdent(parameterNamed(nme.OUTER)) setPos tree.pos
else
super.transform(tree)
@@ -570,9 +586,15 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
else transform(tree.changeOwner(oldowner -> primaryConstr.symbol))
}
+
+ // TODO: we probably can't emit an Assign tree after typers, need to Apply the setter
// Create an assignment to class field `to` with rhs `from`
def mkAssign(to: Symbol, from: Tree): Tree =
- localTyper.typedPos(to.pos) { Assign(Select(This(clazz), to), from) }
+ localTyper.typedPos(to.pos) {
+ val qual = Select(This(clazz), to)
+ if (to.isSetter) Apply(qual, List(from))
+ else Assign(qual, from)
+ }
// Create code to copy parameter to parameter accessor field.
// If parameter is $outer, check that it is not null so that we NPE
@@ -623,44 +645,76 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
}
}
-
for (stat <- stats) {
val statSym = stat.symbol
+ // Move the RHS of a Val/Def (traits don't have vals, their getter holds the RHS) to the appropriate part of the ctor.
+ // If the val def is an early initialized or a parameter accessor,
+ // it goes before the superclass constructor call, otherwise it goes after.
+ // A lazy val's effect is not moved to the constructor, as it is delayed.
+ def moveEffectToCtor(mods: Modifiers, rhs: Tree) = {
+ val initializingRhs =
+ if (statSym.isLazy || rhs.isInstanceOf[Literal]) EmptyTree
+ else if (!mods.hasStaticFlag) intoConstructor(statSym, rhs)
+ else rhs
+
+ if (initializingRhs ne EmptyTree) {
+ val initPhase =
+ if (mods hasFlag STATIC) classInitStatBuf
+ else if (mods hasFlag PRESUPER | PARAMACCESSOR) constrPrefixBuf
+ else constrStatBuf
+
+ val memoized = mustMemoize(statSym)
+
+ val effect =
+ if (memoized) {
+ val assignSym =
+ if (statSym.isGetter) statSym.asInstanceOf[MethodSymbol].referenced //setterIn(clazz, hasExpandedName = false) // not yet expanded -- see Mixin
+ else statSym
+
+ assert(assignSym ne NoSymbol, stat)
+ mkAssign(assignSym, initializingRhs)
+ } else initializingRhs
+
+ initPhase += effect
+ memoized
+ } else false
+ }
+
stat match {
// recurse on class definition, store in defBuf
case _: ClassDef => defBuf += new ConstructorTransformer(unit).transform(stat)
+ // a concrete trait getter's RHS is treated like a ValDef
+ // (the actual field isn't emitted until Mixin augments the class that inherits the trait)
+ case DefDef(mods, _, _, _, _, rhs) if inTrait && statSym.isAccessor =>
+ defBuf +=
+ if (statSym.isGetter && (rhs ne EmptyTree)) {
+ val memoized = moveEffectToCtor(mods, rhs)
+ if (memoized) {
+ statSym setFlag (DEFERRED | lateDEFERRED)
+ deriveDefDef(dd)(_ => EmptyTree)
+ } else stat
+ } else {
+ if (statSym.isSetter) statSym setFlag (DEFERRED | lateDEFERRED)
+ stat
+ }
+
// methods (except primary constructor) go into template
// (non-primary ctors --> auxConstructorBuf / regular defs --> defBuf)
case _: DefDef if statSym.isPrimaryConstructor => ()
case _: DefDef if statSym.isConstructor => auxConstructorBuf += stat
case _: DefDef => defBuf += stat
- // val defs with constant right-hand sides are eliminated.
- case _: ValDef if statSym.info.isInstanceOf[ConstantType] => ()
-
- // For all other val defs, an empty valdef goes into the template.
- // Additionally, non-lazy vals are initialized by an assignment in:
+ // If a val needs a field, an empty valdef goes into the template.
+ // Except for lazy and ConstantTyped vals, the field is initialized by an assignment in:
// - the class initializer (static),
// - the constructor, before the super call (early initialized or a parameter accessor),
// - the constructor, after the super call (regular val).
case ValDef(mods, _, _, rhs) =>
- val initializingRhs =
- if (statSym.isLazy) EmptyTree
- else if (!mods.hasStaticFlag) intoConstructor(statSym, rhs)
- else rhs
-
- if (initializingRhs ne EmptyTree) {
- val initPhase =
- if (mods hasFlag STATIC) classInitStatBuf
- else if (mods hasFlag PRESUPER | PARAMACCESSOR) constrPrefixBuf
- else constrStatBuf
-
- initPhase += mkAssign(statSym, initializingRhs)
- }
+ val memoized = moveEffectToCtor(mods, rhs)
- defBuf += deriveValDef(stat)(_ => EmptyTree)
+ if (memoized) defBuf += deriveValDef(stat)(_ => EmptyTree)
// all other statements go into the constructor
case _ => constrStatBuf += intoConstructor(impl.symbol, stat)
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index ddf003bb981..bc59def2799 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -379,7 +379,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
}
val functionType = definitions.functionType(functionParamTypes, functionResultType)
- val (functionalInterface, isSpecialized) = java8CompatFunctionalInterface(target, functionType)
+ val (functionalInterface, samMethod, isSpecialized) = java8CompatFunctionalInterface(target, functionType)
if (functionalInterface.exists) {
// Create a symbol representing a fictional lambda factory method that accepts the captured
// arguments and returns a Function.
@@ -407,7 +407,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// The backend needs to know the target of the lambda and the functional interface in order
// to emit the invokedynamic instruction. We pass this information as tree attachment.
- apply.updateAttachment(LambdaMetaFactoryCapable(lambdaTarget, arity, functionalInterface))
+ apply.updateAttachment(LambdaMetaFactoryCapable(lambdaTarget, arity, functionalInterface, samMethod))
InvokeDynamicLambda(apply)
} else {
val anonymousClassDef = makeAnonymousClass
@@ -566,24 +566,25 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
}
}
- final case class LambdaMetaFactoryCapable(target: Symbol, arity: Int, functionalInterface: Symbol)
+ final case class LambdaMetaFactoryCapable(target: Symbol, arity: Int, functionalInterface: Symbol, samMethod: Symbol)
// The functional interface that can be used to adapt the lambda target method `target` to the
// given function type. Returns `NoSymbol` if the compiler settings are unsuitable.
- private def java8CompatFunctionalInterface(target: Symbol, functionType: Type): (Symbol, Boolean) = {
+ private def java8CompatFunctionalInterface(target: Symbol, functionType: Type): (Symbol, Symbol, Boolean) = {
val canUseLambdaMetafactory = settings.isBCodeActive
- val sym = functionType.typeSymbol
- val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage
- val name1 = specializeTypes.specializedFunctionName(sym, functionType.typeArgs)
- val paramTps :+ restpe = functionType.typeArgs
- val arity = paramTps.length
- val isSpecialized = name1.toTypeName != sym.name
- val functionalInterface = if (!isSpecialized) {
- currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction(arity)
+ val clazz = functionType.typeSymbol
+ val specializedFunction = specializeTypes.specializedFunctionClass(clazz, functionType.typeArgs)
+ val isSpecialized = specializedFunction != clazz
+ val genericApply = clazz.info.member(nme.apply)
+ val samMethod = if (isSpecialized) {
+ specializeTypes.specializedOverloaded(genericApply, functionType.typeArgs)
} else {
- pack.info.decl(name1.toTypeName.prepend("J"))
+ genericApply
}
- (if (canUseLambdaMetafactory) functionalInterface else NoSymbol, isSpecialized)
+ val x = if (canUseLambdaMetafactory) {
+ specializedFunction
+ } else NoSymbol
+ (x, samMethod, isSpecialized)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 833f25537c0..85b8cc8e979 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -12,8 +12,7 @@ import symtab._
import Flags._
import scala.reflect.internal.Mode._
-abstract class Erasure extends AddInterfaces
- with scala.reflect.internal.transform.Erasure
+abstract class Erasure extends InfoTransform with scala.reflect.internal.transform.Erasure
with typechecker.Analyzer
with TypingTransformers
with ast.TreeDSL
@@ -376,6 +375,20 @@ abstract class Erasure extends AddInterfaces
override def transformInfo(sym: Symbol, tp: Type): Type =
transformMixinInfo(super.transformInfo(sym, tp))
+ def transformMixinInfo(tp: Type): Type = tp match {
+ case ClassInfoType(parents, decls, clazz) if clazz.isPackageClass || !clazz.isJavaDefined =>
+ val parents1 = parents match {
+ case Nil => Nil
+ case hd :: tl =>
+ assert(!hd.typeSymbol.isTrait, clazz)
+ if (clazz.isTrait) ObjectTpe :: tl
+ else parents
+ }
+ ClassInfoType(parents1, decls, clazz)
+ case _ =>
+ tp
+ }
+
val deconstMap = new TypeMap {
// For some reason classOf[Foo] creates ConstantType(Constant(tpe)) with an actual Type for tpe,
// which is later translated to a Class. Unfortunately that means we have bugs like the erasure
@@ -1161,10 +1174,10 @@ abstract class Erasure extends AddInterfaces
val tree1 = preTransformer.transform(tree)
// log("tree after pretransform: "+tree1)
exitingErasure {
- val tree2 = mixinTransformer.transform(tree1)
+ //val tree2 = mixinTransformer.transform(tree1)
// debuglog("tree after addinterfaces: \n" + tree2)
- newTyper(rootContextPostTyper(unit, tree)).typed(tree2)
+ newTyper(rootContextPostTyper(unit, tree)).typed(tree1)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index f12f6c4e185..3576af18e98 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -122,49 +122,25 @@ abstract class ExplicitOuter extends InfoTransform
clazz.fullName == mixin.fullName
}
- /**
- * The type transformation method:
- *
- *
- * -
- * Add an outer parameter to the formal parameters of a constructor
- * in an inner non-trait class;
- *
- * -
- * Add a protected $outer field to an inner class which is
- * not a trait.
- *
- * -
- *
- * Add an outer accessor $outer$$C to every inner class
- * with fully qualified name C that is not an interface.
- * The outer accessor is abstract for traits, concrete for other
- * classes.
- *
- *
- * 3a. Also add overriding accessor defs to every class that inherits
- * mixin classes with outer accessor defs (unless the superclass
- * already inherits the same mixin).
- *
- *
- * -
- * Make all super accessors and modules in traits non-private, mangling
- * their names.
- *
- * -
- * Remove protected flag from all members of traits.
- *
- *
- * Note: this transformInfo need not be reflected as the JVM reflection already
- * elides outer pointers.
- */
+ /** The type transformation method:
+ *
+ * 1. Add an outer parameter to the formal parameters of a constructor
+ * in a non-trait inner class;
+ * 2. Add a protected $outer field to a non-trait inner class.
+ * 3. Add an outer accessor $outer$$C to every inner class
+ * with fully qualified name C that is not an interface.
+ * The outer accessor is abstract for traits, concrete for other
+ * classes.
+ * 4. Also add overriding accessor defs to every class that inherits
+ * mixin classes with outer accessor defs (unless the superclass
+ * already inherits the same mixin).
+ *
+ * Note: this transformInfo need not be reflected as the JVM reflection already
+ * elides outer pointers.
+ */
def transformInfo(sym: Symbol, tp: Type): Type = tp match {
case MethodType(params, restpe1) =>
val restpe = transformInfo(sym, restpe1)
- if (sym.owner.isTrait && ((sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isModule)) { // 5
- sym.makeNotPrivate(sym.owner)
- }
- if (sym.owner.isTrait && sym.isProtected) sym setFlag notPROTECTED // 6
if (sym.isClassConstructor && isInner(sym.owner)) { // 1
val p = sym.newValueParameter(innerClassConstructorParamName, sym.pos)
.setInfo(sym.owner.outerClass.thisType)
@@ -172,6 +148,7 @@ abstract class ExplicitOuter extends InfoTransform
} else if (restpe ne restpe1)
MethodType(params, restpe)
else tp
+
case ClassInfoType(parents, decls, clazz) =>
var decls1 = decls
if (isInner(clazz) && !clazz.isInterface) {
@@ -180,7 +157,7 @@ abstract class ExplicitOuter extends InfoTransform
if (hasOuterField(clazz)) //2
decls1 enter newOuterField(clazz)
}
- if (!clazz.isTrait && !parents.isEmpty) {
+ if (!clazz.isTrait && !parents.isEmpty) { // 4
for (mc <- clazz.mixinClasses) {
val mixinOuterAcc: Symbol = exitingExplicitOuter(outerAccessor(mc))
if (mixinOuterAcc != NoSymbol) {
@@ -195,21 +172,14 @@ abstract class ExplicitOuter extends InfoTransform
}
}
}
- if (decls1 eq decls) tp else ClassInfoType(parents, decls1, clazz)
+ if (decls1 eq decls) tp
+ else ClassInfoType(parents, decls1, clazz)
+
case PolyType(tparams, restp) =>
val restp1 = transformInfo(sym, restp)
if (restp eq restp1) tp else PolyType(tparams, restp1)
- case _ =>
- // Local fields of traits need to be unconditionally unprivatized.
- // Reason: Those fields might need to be unprivatized if referenced by an inner class.
- // On the other hand, mixing in the trait into a separately compiled
- // class needs to have a common naming scheme, independently of whether
- // the field was accessed from an inner class or not. See #2946
- if (sym.owner.isTrait && sym.isLocalToThis &&
- (sym.getterIn(sym.owner.toInterface) == NoSymbol))
- sym.makeNotPrivate(sym.owner)
- tp
+ case tp => tp
}
/** A base class for transformers that maintain outerParam
@@ -294,7 +264,12 @@ abstract class ExplicitOuter extends InfoTransform
}
}
- /**
+ /** TODO: Revise this.... We shouldn't use makeNotPrivate until all subsequent phases are able to resolve symbolically
+ * (e.g., if we name mangle a getter, we can no longer look up the setter unless its name is also name mangled)
+ * We also shouldn't be messing with privacy that's unrelated to outer accessors.
+ * Since traits are now compiled to java interfaces, protected has the same applicability as for classes.
+ *
+ *
* The phase performs the following transformations on terms:
*
*
@@ -441,8 +416,12 @@ abstract class ExplicitOuter extends InfoTransform
else atPos(tree.pos)(outerPath(outerValue, currentClass.outerClass, sym)) // (5)
case Select(qual, name) =>
- // make not private symbol accessed from inner classes, as well as
+ // TODO: move this to the end of the pipeline, as it breaks member lookup
+ // (e.g., getter <> setter correlation is by name, but we could use the referenced field for that...?)
+ //
+ // symbols accessed from inner classes, as well as
// symbols accessed from @inline methods
+ // are made not-private (name mangling to emulate privacy)
//
// See SI-6552 for an example of why `sym.owner.enclMethod hasAnnotation ScalaInlineClass`
// is not suitable; if we make a method-local class non-private, it mangles outer pointer names.
@@ -452,10 +431,12 @@ abstract class ExplicitOuter extends InfoTransform
if ((currentClass != sym.owner || enclMethodIsInline) && !sym.isMethodWithExtension)
sym.makeNotPrivate(sym.owner)
- val qsym = qual.tpe.widen.typeSymbol
- if (sym.isProtected && //(4)
- (qsym.isTrait || !(qual.isInstanceOf[Super] || (qsym isSubClass currentClass))))
+ //(4)
+ if (sym.isProtected &&
+ !qual.isInstanceOf[Super] &&
+ !(qual.tpe.widen.typeSymbol isSubClass currentClass))
sym setFlag notPROTECTED
+
super.transform(tree)
case Apply(sel @ Select(qual, nme.CONSTRUCTOR), args) if isInner(sel.symbol.owner) =>
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index fbb03077734..16470a9dd0e 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -41,8 +41,8 @@ abstract class Flatten extends InfoTransform {
}
private def liftSymbol(sym: Symbol) {
liftClass(sym)
- if (sym.needsImplClass)
- liftClass(erasure implClass sym)
+// if (sym.needsImplClass)
+// liftClass(erasure implClass sym)
}
// This is a short-term measure partially working around objects being
// lifted out of parameterized classes, leaving them referencing
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index b6695efb0b7..0d98a778e4e 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -56,13 +56,15 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
import symtab.Flags._
/** Perform the following transformations:
- * - for a lazy accessor inside a method, make it check the initialization bitmap
- * - for all methods, add enough int vars to allow one flag per lazy local value
- * - blocks in template bodies behave almost like methods. A single bitmaps section is
- * added in the first block, for all lazy values defined in such blocks.
- * - remove ACCESSOR flags: accessors in traits are not statically implemented,
- * but moved to the host class. local lazy values should be statically implemented.
- */
+ * - for a lazy accessor inside a method, make it check the initialization bitmap
+ * - for all methods, add enough int vars to allow one flag per lazy local value
+ * - blocks in template bodies behave almost like methods. A single bitmaps section is
+ * added in the first block, for all lazy values defined in such blocks.
+ * - remove ACCESSOR flags:
+ * - accessors in traits are not statically implemented, but moved to the host class.
+ * see LocalLazyVal in test/files/run/lazy-traits.scala (8d96aea0a2) -- TODO: affected by new trait compilation (default methods)?
+ * - local lazy values should be statically implemented.
+ */
override def transform(tree: Tree): Tree = {
val sym = tree.symbol
curTree = tree
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index a079a76ce7c..5c94f777aa3 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -7,9 +7,33 @@ package scala.tools.nsc
package transform
import symtab._
-import Flags._
+import reflect.internal.Flags._
import scala.collection.{ mutable, immutable }
+/** TODO: this describes my current goal for the trait-default scheme, not (yet) the actual implementation
+ *
+ * So far, we've tried to treat classes and traits in the same way as much as possible.
+ * Except, for traits:
+ * - Fields have been removed during Constructors, which also made their accessors abstract,
+ * while setting the MIXEDIN flag to track that the accessors need to be implemented here.
+ * (Constructors needs to see the fields to the init code to the constructor.
+ * Note that getters for vals without storage are concrete already in the trait -- see `typeNeedsNoStorage`)
+ * - An outer accessor is abstract
+ * - A super accessor is abstract
+ * - A lazy val is an abstract getter and a concrete method to compute the rhs (and perform its side-effects)
+ * - TODO: (lifted) objects
+ *
+ * In classes that extends traits, it's time to face the music:
+ * - an overriding method is added for each trait method definition with the override keyword,
+ * as well as for each method that occurs more than once in the linearisation:
+ * ```trait A { def foo }; trait B { def foo}; class C extends A with B { /* must override foo */ }```
+ * - fields are created
+ * - accessors are implemented (for fields, outers & supers)
+ * - lazy vals get bitmaps, getter does its lazy thing, using the compute method in the trait
+ * - TODO: (lifted) objects
+ *
+ *
+ */
abstract class Mixin extends InfoTransform with ast.TreeDSL {
import global._
import definitions._
@@ -31,44 +55,54 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// --------- helper functions -----------------------------------------------
- /** A member of a trait is implemented statically if its implementation after the
- * mixin transform is in the static implementation module. To be statically
- * implemented, a member must be a method that belonged to the trait's implementation class
- * before (i.e. it is not abstract). Not statically implemented are
- * - non-private modules: these are implemented directly in the mixin composition class
- * (private modules, on the other hand, are implemented statically, but their
- * module variable is not. all such private modules are lifted, because
- * non-lifted private modules have been eliminated in ExplicitOuter)
- * - field accessors and superaccessors, except for lazy value accessors which become initializer
- * methods in the impl class (because they can have arbitrary initializers)
- */
- private def isImplementedStatically(sym: Symbol) = (
- sym.owner.isImplClass
- && sym.isMethod
- && (!sym.isModule || sym.hasFlag(PRIVATE | LIFTED))
- && (!(sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isLazy)
- )
-
- /** A member of a trait is static only if it belongs only to the
- * implementation class, not the interface, and it is implemented
- * statically.
- */
- private def isStaticOnly(sym: Symbol) =
- isImplementedStatically(sym) && sym.isImplOnly
-
- /** A member of a trait is forwarded if it is implemented statically and it
- * is also visible in the trait's interface. In that case, a forwarder to
- * the member's static implementation will be added to the class that
- * inherits the trait.
- */
- private def isForwarded(sym: Symbol) =
- isImplementedStatically(sym) && !sym.isImplOnly
-
- /** Maps the type of an implementation class to its interface;
- * maps all other types to themselves.
- */
- private def toInterface(tp: Type): Type =
- enteringMixin(tp.typeSymbol.toInterface).tpe
+ // TODO: not much of this makes sense, and I can't reproduce this with examples
+ /** To be statically implemented, a trait member must be a method that
+ * belonged to the trait's implementation class before (i.e. it is not abstract).
+ *
+ * In other words (???), its implementation after the mixin transform
+ * is in the static implementation module.
+ *
+ * Non-private modules are implemented non-statically:
+ * they are implemented directly in the mixin composition class.
+ *
+ * Private modules are implemented statically, but their
+ * module variable is not. Private modules are known to have been lifted,
+ * because non-lifted private modules have been eliminated in ExplicitOuter.
+ *
+ * Not statically implemented are
+ * -
+ * - field accessors and superaccessors, except for
+ *
+ * Lazy value accessors become initializer methods in the impl class
+ * because they can have arbitrary initializers.
+ */
+// private def isImplementedStatically(sym: Symbol) = (
+// sym.owner.isImplClass
+// && sym.isMethod
+// && (!sym.isModule || sym.hasFlag(PRIVATE | LIFTED))
+// && (!(sym hasFlag (ACCESSOR | SUPERACCESSOR)) || sym.isLazy)
+// )
+//
+// /** A member of a trait is static only if it belongs only to the
+// * implementation class, not the interface, and it is implemented
+// * statically.
+// */
+// private def isStaticOnly(sym: Symbol) =
+// isImplementedStatically(sym) && sym.isImplOnly
+//
+// /** A member of a trait is forwarded if it is implemented statically and it
+// * is also visible in the trait's interface. In that case, a forwarder to
+// * the member's static implementation will be added to the class that
+// * inherits the trait.
+// */
+// private def isForwarded(sym: Symbol) =
+// isImplementedStatically(sym) && !sym.isImplOnly
+//
+// /** Maps the type of an implementation class to its interface;
+// * maps all other types to themselves.
+// */
+// private def toInterface(tp: Type): Type =
+// enteringMixin(tp.typeSymbol.toInterface).tpe
private def isFieldWithBitmap(field: Symbol) = {
field.info // ensure that nested objects are transformed
@@ -100,42 +134,19 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Maps all parts of this type that refer to implementation classes to
* their corresponding interfaces.
*/
- private val toInterfaceMap = new TypeMap {
- def apply(tp: Type): Type = mapOver( tp match {
- case TypeRef(pre, sym, args) if sym.isImplClass =>
- typeRef(pre, enteringMixin(sym.toInterface), args)
- case _ => tp
- })
- }
+// private val toInterfaceMap = new TypeMap {
+// def apply(tp: Type): Type = mapOver( tp match {
+// case TypeRef(pre, sym, args) if sym.isImplClass =>
+// typeRef(pre, enteringMixin(sym.toInterface), args)
+// case _ => tp
+// })
+// }
/** The implementation class corresponding to a currently compiled interface.
* todo: try to use Symbol.implClass instead?
*/
- private def implClass(iface: Symbol) = iface.implClass orElse (erasure implClass iface)
+ private def implClass(iface: Symbol) = iface.implClass //orElse (erasure implClass iface)
- /** Returns the symbol that is accessed by a super-accessor in a mixin composition.
- *
- * @param base The class in which everything is mixed together
- * @param member The symbol statically referred to by the superaccessor in the trait
- * @param mixinClass The mixin class that produced the superaccessor
- */
- private def rebindSuper(base: Symbol, member: Symbol, mixinClass: Symbol): Symbol =
- exitingSpecialize {
- var bcs = base.info.baseClasses.dropWhile(mixinClass != _).tail
- var sym: Symbol = NoSymbol
- debuglog("starting rebindsuper " + base + " " + member + ":" + member.tpe +
- " " + mixinClass + " " + base.info.baseClasses + "/" + bcs)
- while (!bcs.isEmpty && sym == NoSymbol) {
- if (settings.debug) {
- val other = bcs.head.info.nonPrivateDecl(member.name)
- debuglog("rebindsuper " + bcs.head + " " + other + " " + other.tpe +
- " " + other.isDeferred)
- }
- sym = member.matchingSymbol(bcs.head, base.thisType).suchThat(sym => !sym.hasFlag(DEFERRED | BRIDGE))
- bcs = bcs.tail
- }
- sym
- }
// --------- type transformation -----------------------------------------------
@@ -156,270 +167,153 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
)
}
- /** Add given member to given class, and mark member as mixed-in.
- */
- def addMember(clazz: Symbol, member: Symbol): Symbol = {
- debuglog("new member of " + clazz + ":" + member.defString)
- clazz.info.decls enter member setFlag MIXEDIN
- }
- def cloneAndAddMember(mixinClass: Symbol, mixinMember: Symbol, clazz: Symbol): Symbol =
- addMember(clazz, cloneBeforeErasure(mixinClass, mixinMember, clazz))
-
- def cloneBeforeErasure(mixinClass: Symbol, mixinMember: Symbol, clazz: Symbol): Symbol = {
- val newSym = enteringErasure {
- // since we used `mixinMember` from the interface that represents the trait that's
- // being mixed in, have to instantiate the interface type params (that may occur in mixinMember's
- // info) as they are seen from the class. We can't use the member that we get from the
- // implementation class, as it's a clone that was made after erasure, and thus it does not
- // know its info at the beginning of erasure anymore.
- val sym = mixinMember cloneSymbol clazz
-
- val erasureMap = erasure.erasure(mixinMember)
- val erasedInterfaceInfo: Type = erasureMap(mixinMember.info)
- val specificForwardInfo = (clazz.thisType baseType mixinClass) memberInfo mixinMember
- val forwarderInfo =
- if (erasureMap(specificForwardInfo) =:= erasedInterfaceInfo)
- specificForwardInfo
- else {
- erasedInterfaceInfo
- }
- // Optimize: no need if mixinClass has no typeparams.
- // !!! JZ Really? What about the effect of abstract types, prefix?
- if (mixinClass.typeParams.isEmpty) sym
- else sym modifyInfo (_ => forwarderInfo)
+ private def doImplementTraitMembers(clazz: Symbol) =
+ !(clazz.isTrait || clazz.isJavaDefined || isPrimitiveValueClass(clazz) || treatedClassInfos(clazz) == clazz.info)
+
+ /** Add all members to be mixed in into a (non-trait-) class
+ * For every mixin trait T that is not also inherited by the superclass:
+ * - for every abstract accessor in T, add a field (expanding its name if needed) and an implementation for that accessor
+ * - for every super accessor in T, add an implementation of that accessor
+ * - for every module in T, add a module
+ *
+ * @pre doImplementTraitMembers(clazz)
+ */
+ def implementTraitMembers(clazz: Symbol, unit: CompilationUnit): Unit = {
+ assert(clazz.info.parents.nonEmpty, clazz)
+ treatedClassInfos(clazz) = clazz.info
+
+ // add `member` to `clazz`, mark as mixed-in.
+ def mixinMemberSym(member: Symbol): Symbol = {
+ debuglog("new member of " + clazz + ":" + member.defString)
+ clazz.info.decls enter member setFlag MIXEDIN
}
- newSym
- }
- /** Add getters and setters for all non-module fields of an implementation
- * class to its interface unless they are already present. This is done
- * only once per class. The mixedin flag is used to remember whether late
- * members have been added to an interface.
- * - lazy fields don't get a setter.
- */
- def addLateInterfaceMembers(clazz: Symbol) {
- if (treatedClassInfos(clazz) != clazz.info) {
- 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. */
- 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 )
- // TODO preserve pre-erasure info?
- clazz.newMethod(field.getterName, field.pos, newFlags) setInfo MethodType(Nil, field.info)
+ def mixinFieldSym(traitMember: Symbol): Unit = {
+ // otherwise mixin a field based on the
+ // #3857, need to retain info before erasure when cloning (since cloning only
+ // carries over the current entry in the type history)
+ val sym = enteringErasure {
+ // so we have a type history entry before erasure
+ clazz.newValue(traitMember.localName, traitMember.pos).setInfo(traitMember.tpe.resultType)
}
+ sym updateInfo traitMember.tpe.resultType // info at current phase
- /* 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))
- val setterName = field.setterName
- val newFlags = field.flags & ~PrivateLocal | ACCESSOR | lateDEFERRED
- val setter = clazz.newMethod(setterName, field.pos, newFlags)
- // TODO preserve pre-erasure info?
- setter setInfo MethodType(setter.newSyntheticValueParams(List(field.info)), UnitTpe)
- if (field.needsExpandedSetterName)
- setter.name = nme.expandedSetterName(setter.name, clazz)
-
- setter
- }
+ val newFlags = (
+ (PrivateLocal)
+ | (traitMember getFlag MUTABLE | LAZY)
+ | (if (traitMember.hasStableFlag) 0 else MUTABLE)
+ )
- clazz.info // make sure info is up to date, so that implClass is set.
- val impl = implClass(clazz) orElse abort("No impl class for " + clazz)
+ mixinMemberSym(sym setFlag newFlags setAnnotations traitMember.annotations)
+ }
- for (member <- impl.info.decls) {
- if (!member.isMethod && !member.isModule && !member.isModuleVar) {
- assert(member.isTerm && !member.isDeferred, member)
- if (member.getterIn(impl).isPrivate) {
- member.makeNotPrivate(clazz) // this will also make getter&setter not private
- }
- val getter = member.getterIn(clazz)
- if (getter == NoSymbol) addMember(clazz, newGetter(member))
- if (!member.tpe.isInstanceOf[ConstantType] && !member.isLazy) {
- val setter = member.setterIn(clazz)
- if (setter == NoSymbol) addMember(clazz, newSetter(member))
- }
- }
+ def mixinAccessorSym(traitClass: Symbol, traitMember: Symbol): Unit = {
+ val sym = enteringErasure {
+ (traitMember cloneSymbol clazz) setInfo (clazz.thisType memberInfo traitMember)
}
- debuglog("new defs of " + clazz + " = " + clazz.info.decls)
+ sym updateInfo (clazz.thisType memberInfo traitMember) // info at current phase
+
+ mixinMemberSym(sym.setPos(clazz.pos).resetFlag(DEFERRED | lateDEFERRED))
}
- }
- /** Add all members to be mixed in into a (non-trait-) class
- * These are:
- * for every mixin trait T that is not also inherited by the superclass:
- * add late interface members to T and then:
- * - if a member M of T is forwarded to the implementation class, add
- * a forwarder for M unless one exists already.
- * The alias of the forwarder is the static member it forwards to.
- * - for every abstract accessor in T, add a field and an implementation for that accessor
- * - for every super accessor in T, add an implementation of that accessor
- * - for every module in T, add a module
- */
- def addMixedinMembers(clazz: Symbol, unit: CompilationUnit) {
- def cloneAndAddMixinMember(mixinClass: Symbol, mixinMember: Symbol): Symbol = (
- cloneAndAddMember(mixinClass, mixinMember, clazz)
- setPos clazz.pos
- resetFlag DEFERRED | lateDEFERRED
- )
- /* Mix in members of implementation class mixinClass into class clazz */
- def mixinImplClassMembers(mixinClass: Symbol, mixinInterface: Symbol) {
- if (!mixinClass.isImplClass) devWarning ("Impl class flag is not set " +
- ((mixinClass.debugLocationString, mixinInterface.debugLocationString)))
-
- for (member <- mixinClass.info.decls ; if isForwarded(member)) {
- val imember = member overriddenSymbol mixinInterface
- imember overridingSymbol clazz match {
- case NoSymbol =>
- if (clazz.info.findMember(member.name, 0, lateDEFERRED, stableOnly = false).alternatives contains imember)
- cloneAndAddMixinMember(mixinInterface, imember).asInstanceOf[TermSymbol] setAlias member
- case _ =>
+ /** The symbol that is accessed by a super-accessor in a mixin composition.
+ *
+ * @param mixinClass The mixin class that produced the superaccessor
+ * @param member The symbol statically referred to by the superaccessor in the trait
+ */
+ def superSym(mixinClass: Symbol, member: Symbol): Symbol = exitingSpecialize {
+ var bcs = clazz.info.baseClasses.dropWhile(mixinClass != _).tail
+ var sym: Symbol = NoSymbol
+ debuglog(s"superSym in $clazz for ${member.defString} in $bcs")
+ while (!bcs.isEmpty && sym == NoSymbol) {
+ if (settings.debug) {
+ val other = bcs.head.info.nonPrivateDecl(member.name)
+ debuglog("rebindsuper " + bcs.head + " " + other + " " + other.tpe +
+ " " + other.isDeferred)
}
+ sym = member.matchingSymbol(bcs.head, clazz.thisType).suchThat(sym => !sym.hasFlag(DEFERRED | BRIDGE))
+ bcs = bcs.tail
}
+
+ sym
}
- /* Mix in members of trait mixinClass into class clazz. Also,
- * for each lazy field in mixinClass, add a link from its mixed in member to its
- * initializer method inside the implclass.
- */
- def mixinTraitMembers(mixinClass: Symbol) {
- // For all members of a trait's interface do:
- for (mixinMember <- mixinClass.info.decls) {
- if (isConcreteAccessor(mixinMember)) {
- if (isOverriddenAccessor(mixinMember, clazz.info.baseClasses))
- devWarning(s"Overridden concrete accessor: ${mixinMember.fullLocationString}")
- else {
- // mixin field accessors
- val mixedInAccessor = cloneAndAddMixinMember(mixinClass, mixinMember)
- if (mixinMember.isLazy) {
- initializer(mixedInAccessor) = (
- implClass(mixinClass).info.decl(mixinMember.name)
- orElse abort("Could not find initializer for " + mixinMember.name)
- )
+ def mixinSuperAccessorSym(traitMember: Symbol, superSym: Symbol): Unit = {
+ val superAccessor = traitMember.cloneSymbol(clazz) setPos clazz.pos
+ assert(superAccessor.alias != NoSymbol, superAccessor)
+ superAccessor.asInstanceOf[TermSymbol] setAlias superSym
+ mixinMemberSym(superAccessor)
+ }
+
+
+ // first complete the superclass with mixed in members
+ if (doImplementTraitMembers(clazz.superClass))
+ implementTraitMembers(clazz.superClass, unit)
+
+ for (traitClass <- clazz.mixinClasses) {
+ // pre-name-hashing dependency tracking for incremental compilation in sbt
+ unit.depends += traitClass
+
+ for (traitMember <- traitClass.info.decls) {
+ // accessors that need an implementation and a field
+ val accessor: Boolean = traitMember.isAccessor
+ val concrete: Boolean = traitMember hasFlag lateDEFERRED
+ val notOverridden: Boolean = !isOverriddenAccessor(traitMember, clazz.info.baseClasses)
+
+ println(s"traitMember: $traitMember $accessor/$concrete/$notOverridden")
+
+ if (accessor) {
+ if (concrete) {
+ if (notOverridden) {
+ mixinAccessorSym(traitClass, traitMember)
+
+ //if (traitMember.isLazy) initializer(mixedInAccessor) = traitMember
+
+ // mixin one field only (this method is called for both accessors)
+ // don't mix in a field at all if it doesn't need storage
+ if (traitMember.isGetter && mustMemoize(traitMember))
+ mixinFieldSym(traitMember)
}
- if (!mixinMember.isSetter)
- mixinMember.tpe match {
- case MethodType(Nil, ConstantType(_)) =>
- // mixinMember is a constant; only getter is needed
- ;
- case MethodType(Nil, TypeRef(_, UnitClass, _)) =>
- // mixinMember is a value of type unit. No field needed
- ;
- case _ => // otherwise mixin a field as well
- // enteringPhase: the private field is moved to the implementation class by erasure,
- // so it can no longer be found in the mixinMember's owner (the trait)
- val accessed = enteringPickler(mixinMember.accessed)
- // #3857, need to retain info before erasure when cloning (since cloning only
- // carries over the current entry in the type history)
- val sym = enteringErasure {
- // so we have a type history entry before erasure
- clazz.newValue(mixinMember.localName, mixinMember.pos).setInfo(mixinMember.tpe.resultType)
- }
- sym updateInfo mixinMember.tpe.resultType // info at current phase
-
- val newFlags = (
- ( PrivateLocal )
- | ( mixinMember getFlag MUTABLE | LAZY)
- | ( if (mixinMember.hasStableFlag) 0 else MUTABLE )
- )
-
- addMember(clazz, sym setFlag newFlags setAnnotations accessed.annotations)
- }
+ else devWarning(s"Overridden concrete accessor: ${traitMember.fullLocationString}")
}
- }
- else if (mixinMember.isSuperAccessor) { // mixin super accessors
- val superAccessor = addMember(clazz, mixinMember.cloneSymbol(clazz)) setPos clazz.pos
- assert(superAccessor.alias != NoSymbol, superAccessor)
-
- rebindSuper(clazz, mixinMember.alias, mixinClass) match {
- case NoSymbol =>
- reporter.error(clazz.pos, "Member %s of mixin %s is missing a concrete super implementation.".format(
- mixinMember.alias, mixinClass))
- case alias1 =>
- superAccessor.asInstanceOf[TermSymbol] setAlias alias1
- }
- }
- else if (mixinMember.isMethod && mixinMember.isModule && mixinMember.hasNoFlags(LIFTED | BRIDGE)) {
+ } else if (traitMember.isSuperAccessor) {
+ val sym = superSym(traitClass, traitMember.alias)
+ if (sym ne NoSymbol) mixinSuperAccessorSym(traitMember, sym)
+ else reporter.error(clazz.pos, s"Member $traitMember of mixin $traitClass is missing a concrete super implementation.")
+ } else if (traitMember.hasAllFlags(MODULE | METHOD) && traitMember.hasNoFlags(LIFTED | BRIDGE)) {
// mixin objects: todo what happens with abstract objects?
- addMember(clazz, mixinMember.cloneSymbol(clazz, mixinMember.flags & ~(DEFERRED | lateDEFERRED)) setPos clazz.pos)
+ mixinMemberSym(traitMember.cloneSymbol(clazz, traitMember.flags & ~(DEFERRED | lateDEFERRED)) setPos clazz.pos)
}
}
}
-
- if (clazz.isJavaDefined || treatedClassInfos(clazz) == clazz.info)
- return
-
- treatedClassInfos(clazz) = clazz.info
- assert(!clazz.isTrait && clazz.info.parents.nonEmpty, clazz)
-
- // first complete the superclass with mixed in members
- addMixedinMembers(clazz.superClass, unit)
-
- for (mc <- clazz.mixinClasses ; if mc hasFlag lateINTERFACE) {
- // @SEAN: adding trait tracking so we don't have to recompile transitive closures
- unit.depends += mc
- addLateInterfaceMembers(mc)
- mixinTraitMembers(mc)
- mixinImplClassMembers(implClass(mc), mc)
- }
}
/** The info transform for this phase does the following:
- * - The parents of every class are mapped from implementation class to interface
- * - Implementation classes become modules that inherit nothing
- * and that define all.
+ *
+ * Moved from explicit outer: TODO: update for new mixin scheme
+ * 5. Make all private super accessors and modules in traits non-private, mangling their names.
+ * 6. (Remove protected flag from all members of traits. TODO: sure this no longer needed?)
+ * 7. All local (private[this]) fields of traits are made not-private. See SI-2946.
+ * Strictly speaking only necessary when the field is referenced
+ * by an inner class, as that class will be lifted out of the
+ * access boundary of the private[this] member. To enable separate compilation,
+ * we must always transform, since other compilation runs have no way of knowing
+ * whether the field was accessed (and thus its name was mangled by
+ * makeNotPrivate to emulate privacy for public members) or not.
*/
- override def transformInfo(sym: Symbol, tp: Type): Type = tp match {
- case ClassInfoType(parents, decls, clazz) =>
- var parents1 = parents
- var decls1 = decls
- if (!clazz.isPackageClass) {
- exitingMixin(clazz.owner.info)
- if (clazz.isImplClass) {
- clazz setFlag lateMODULE
- var sourceModule = clazz.owner.info.decls.lookup(sym.name.toTermName)
- if (sourceModule == NoSymbol) {
- sourceModule = (
- clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE)
- setModuleClass sym.asInstanceOf[ClassSymbol]
- )
- clazz.owner.info.decls enter sourceModule
- }
- else {
- sourceModule setPos sym.pos
- if (sourceModule.flags != MODULE) {
- log(s"!!! Directly setting sourceModule flags for $sourceModule from ${sourceModule.flagString} to MODULE")
- sourceModule.flags = MODULE
- }
- }
- sourceModule setInfo sym.tpe
- // Companion module isn't visible for anonymous class at this point anyway
- assert(clazz.sourceModule != NoSymbol || clazz.isAnonymousClass, s"$clazz has no sourceModule: $sym ${sym.tpe}")
- parents1 = List()
- decls1 = newScopeWith(decls.toList filter isImplementedStatically: _*)
- } else if (!parents.isEmpty) {
- parents1 = parents.head :: (parents.tail map toInterface)
- }
- }
- //decls1 = enteringPhase(phase.next)(newScopeWith(decls1.toList: _*))//debug
- if ((parents1 eq parents) && (decls1 eq decls)) tp
- else ClassInfoType(parents1, decls1, clazz)
-
- case MethodType(params, restp) =>
- toInterfaceMap(
- if (isImplementedStatically(sym)) {
- val ownerParam = sym.newSyntheticValueParam(toInterface(sym.owner.typeOfThis))
- MethodType(ownerParam :: params, restp)
- } else
- tp)
-
- case _ =>
- tp
+ override def transformInfo(sym: Symbol, tp: Type): Type = {
+ if (sym.isPrivate && sym.owner.isTrait) {
+ // TODO: why not do this from the start? (maybe because it name-mangles depending on the class??)
+ if ((sym hasFlag (ACCESSOR | SUPERACCESSOR))
+ || sym.isModule // 5
+ || sym.isLocalToThis) // 7 TODO what did `&& sym.getterIn(sym.owner.toInterface) == NoSymbol` do?
+ sym.makeNotPrivate(sym.owner)
+ }
+ tp
}
+
/** Return a map of single-use fields to the lazy value that uses them during initialization.
* Each field has to be private and defined in the enclosing class, and there must
* be exactly one lazy value using it.
@@ -501,65 +395,38 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
+ // TODO in namers: if(sym.owner.isTrait && sym.isSetter && !sym.isDeferred) sym.addAnnotation(TraitSetterAnnotationClass)
+
/** The first transform; called in a pre-order traversal at phase mixin
- * (that is, every node is processed before its children).
- * What transform does:
- * - For every non-trait class, add all mixed in members to the class info.
- * - For every trait, add all late interface members to the class info
- * - For every static implementation method:
- * - remove override flag
- * - create a new method definition that also has a `self` parameter
- * (which comes first) Iuli: this position is assumed by tail call elimination
- * on a different receiver. Storing a new 'this' assumes it is located at
- * index 0 in the local variable table. See 'STORE_THIS' and GenASM.
- * - Map implementation class types in type-apply's to their interfaces
- * - Remove all fields in implementation classes
- */
+ * (that is, every node is processed before its children).
+ *
+ * For every non-trait class, add all mixed in members to the class info.
+ */
private def preTransform(tree: Tree): Tree = {
val sym = tree.symbol
+ val clazz = sym.owner
tree match {
- case Template(parents, self, body) =>
+ // Add super-trait constructor calls `super[mix].$init$()` (in reverse-linearization order) to the body of the ctor
+ case DefDef(_,_,_,_,_, Block(_ :: _, _)) if sym.isClassConstructor && sym.isPrimaryConstructor && clazz != ArrayClass =>
+ deriveDefDef(tree) { case tree@Block(stats, expr) =>
+ def typedCtorCall(`trait`: Symbol): Tree =
+ typedPos(expr.pos) { Apply(Select(This(clazz), `trait`.primaryConstructor), List()) }
+
+ // check `hasExistingSymbol` (via `hasSymbolWhich`) because `supercall` could be a block (named / default args)
+ val (preSuper, superCall :: postSuperOrig) = stats span (_ hasSymbolWhich (_ hasFlag PRESUPER))
+ val postSuper = (clazz.mixinClasses map typedCtorCall) reverse_::: postSuperOrig
+ treeCopy.Block(tree, preSuper ::: (superCall :: postSuper), expr)
+ }
+
+ case Template(parents, self, body) if doImplementTraitMembers(currentOwner) =>
localTyper = erasure.newTyper(rootContext.make(tree, currentOwner))
exitingMixin(currentOwner.owner.info)//todo: needed?
- if (!currentOwner.isTrait && !isPrimitiveValueClass(currentOwner))
- addMixedinMembers(currentOwner, unit)
- else if (currentOwner hasFlag lateINTERFACE)
- addLateInterfaceMembers(currentOwner)
+ implementTraitMembers(currentOwner, unit)
tree
- case DefDef(_, _, _, vparams :: Nil, _, _) =>
- if (currentOwner.isImplClass) {
- if (isImplementedStatically(sym)) {
- sym setFlag notOVERRIDE
- self = sym.newValueParameter(nme.SELF, sym.pos) setInfo toInterface(currentOwner.typeOfThis)
- val selfdef = ValDef(self) setType NoType
- copyDefDef(tree)(vparamss = List(selfdef :: vparams))
- }
- else EmptyTree
- }
- else {
- if (currentOwner.isTrait && sym.isSetter && !enteringPickler(sym.isDeferred)) {
- sym.addAnnotation(TraitSetterAnnotationClass)
- }
- tree
- }
- // !!! What is this doing, and why is it only looking for exactly
- // one type parameter? It would seem to be
- // "Map implementation class types in type-apply's to their interfaces"
- // from the comment on preTransform, but is there some way we should know
- // that impl class types in type applies can only appear in single
- // type parameter type constructors?
- case Apply(tapp @ TypeApply(fn, List(arg)), List()) =>
- if (arg.tpe.typeSymbol.isImplClass) {
- val ifacetpe = toInterface(arg.tpe)
- arg setType ifacetpe
- tapp setType MethodType(Nil, ifacetpe)
- tree setType ifacetpe
- }
- tree
- case ValDef(_, _, _, _) if currentOwner.isImplClass =>
- EmptyTree
+
+
case _ =>
tree
}
@@ -1028,28 +895,33 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
else mkCheckedAccessor(clazz, readValue, fieldOffset(getter), getter.pos, getter)
}
- def setterBody(setter: Symbol) = {
- val getter = setter.getterIn(clazz)
+ // If this is a setter of a mixed-in field which is overridden by another mixin,
+ // the trait setter of the overridden one does not need to do anything - the
+ // trait setter of the overriding field will initialize the field.
+ def setterBody(setter: Symbol) =
+ if (isOverriddenSetter(setter)) UNIT
+ else {
+ val getter = setter.getterIn(clazz)
- // A trait with a field of type Unit creates a trait setter (invoked by the
- // implementation class constructor), like for any other trait field.
- // However, no actual field is created in the class that mixes in the trait.
- // Therefore the setter does nothing (except setting the -Xcheckinit flag).
+ // A trait with a field of type Unit creates a trait setter (invoked by the
+ // implementation class constructor), like for any other trait field.
+ // However, no actual field is created in the class that mixes in the trait.
+ // Therefore the setter does nothing (except setting the -Xcheckinit flag).
- val setInitFlag =
- if (!needsInitFlag(getter)) Nil
- else List(mkSetFlag(clazz, fieldOffset(getter), getter, bitmapKind(getter)))
+ val setInitFlag =
+ if (!needsInitFlag(getter)) Nil
+ else List(mkSetFlag(clazz, fieldOffset(getter), getter, bitmapKind(getter)))
- val fieldInitializer =
- if (isUnitGetter(getter)) Nil
- else List(Assign(fieldAccess(setter), Ident(setter.firstParam)))
+ val fieldInitializer =
+ if (isUnitGetter(getter)) Nil
+ else List(Assign(fieldAccess(setter), Ident(setter.firstParam)))
- (fieldInitializer ::: setInitFlag) match {
- case Nil => UNIT
- // If there's only one statement, the Block factory does not actually create a Block.
- case stats => Block(stats: _*)
+ (fieldInitializer ::: setInitFlag) match {
+ case Nil => UNIT
+ // If there's only one statement, the Block factory does not actually create a Block.
+ case stats => Block(stats: _*)
+ }
}
- }
def isUnitGetter(getter: Symbol) = getter.tpe.resultType.typeSymbol == UnitClass
def fieldAccess(accessor: Symbol) = Select(This(clazz), accessor.accessed)
@@ -1060,6 +932,22 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
isOverriddenAccessor(other.getterIn(other.owner), clazz.info.baseClasses)
}
+ // Emitting code for Function[0|1|2]
+ if (isFunctionSymbol(clazz) && clazz.isSpecialized) {
+ val sym = clazz.info.decl(nme.apply)
+ // def apply(v1: Object)Object = apply(v1.unbox).box
+ val functionClass = clazz.baseClasses(1)
+ val genericApply = functionClass.info.member(nme.apply) // why `member` and not `decl`?
+ val bridge = genericApply.cloneSymbol(clazz, /*BRIDGE |*/ METHOD | JAVA_DEFAULTMETHOD | DEFERRED).setPos(sym.pos)
+ addDefDef(bridge,
+ Apply(gen.mkAttributedSelect(gen.mkAttributedThis(sym.owner), sym), bridge.paramss.head.map(p => gen.mkAttributedIdent(p))))
+
+ // def apply$mcII$sp(v1: Int)Int
+ val specializedApply = specializeTypes.specializedOverloaded(genericApply, exitingSpecialize(clazz.info.baseType(functionClass).typeArgs))
+ val m2 = specializedApply.cloneSymbol(clazz, METHOD | DEFERRED).setPos(sym.pos)
+ addDefDef(m2.setPos(sym.pos))
+ }
+
// for all symbols `sym` in the class definition, which are mixed in:
for (sym <- clazz.info.decls ; if sym hasFlag MIXEDIN) {
// if current class is a trait interface, add an abstract method for accessor `sym`
@@ -1068,19 +956,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
// if class is not a trait add accessor definitions
else if (!clazz.isTrait) {
- if (isConcreteAccessor(sym)) {
- // add accessor definitions
- addDefDef(sym, {
- if (sym.isSetter) {
- // If this is a setter of a mixed-in field which is overridden by another mixin,
- // the trait setter of the overridden one does not need to do anything - the
- // trait setter of the overriding field will initialize the field.
- if (isOverriddenSetter(sym)) UNIT
- else setterBody(sym)
- }
- else getterBody(sym)
- })
- }
+ if (sym.isAccessor) addDefDef(sym, if (sym.isSetter) setterBody(sym) else getterBody(sym))
else if (sym.isModule && !(sym hasFlag LIFTED | BRIDGE)) {
// add modules
val vsym = sym.owner.newModuleVarSymbol(sym)
@@ -1103,12 +979,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// add superaccessors
addDefDef(sym)
}
- else {
- // add forwarders
- assert(sym.alias != NoSymbol, sym)
- // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString)
- if (!sym.isMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident)))
- }
+ // TODO: override methods to encode linearization order
+// else {
+// // add forwarders
+// assert(sym.alias != NoSymbol, sym)
+// // debuglog("New forwarder: " + sym.defString + " => " + sym.alias.defString)
+// if (!sym.isMacro) addDefDef(sym, Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: sym.paramss.head.map(Ident)))
+// }
}
}
stats1 = add(stats1, newDefs.toList)
@@ -1151,8 +1028,8 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
// change every node type that refers to an implementation class to its
// corresponding interface, unless the node's symbol is an implementation class.
- if (tree.tpe.typeSymbol.isImplClass && ((sym eq null) || !sym.isImplClass))
- tree modifyType toInterface
+// if (tree.tpe.typeSymbol.isImplClass && ((sym eq null) || !sym.isImplClass))
+// tree modifyType toInterface
tree match {
case templ @ Template(parents, self, body) =>
@@ -1167,6 +1044,41 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
case Apply(TypeApply(Select(qual, _), targ :: _), _) if isCastSymbol(sym) && (qual.tpe <:< targ.tpe) =>
qual
+ case dd @ DefDef(_, _, _, vparamss, _, EmptyTree) if isFunctionSymbol(sym.owner) =>
+ // why only exclude toString?
+ val addDefault = enteringPhase(currentRun.erasurePhase.prev)(!sym.isDeferred) && sym.name != nme.toString_ // before lateDEFERRED
+ if (addDefault) {
+ def implSym = implClass(sym.owner).info.member(sym.name)
+ sym.setFlag(Flags.JAVA_DEFAULTMETHOD)
+ val tree = Apply(staticRef(implSym), gen.mkAttributedThis(sym.owner) :: sym.paramss.head.map(gen.mkAttributedIdent))
+ val app = typedPos(tree.pos)(tree)
+ copyDefDef(dd)(rhs = app)
+ } else if (sym.owner.isSpecialized && sym.name == nme.apply) {
+ val clazz = sym.owner
+ val functionClass = clazz.baseClasses(1)
+ val substitutedApply = clazz.info.decl(nme.apply)
+ val genericApply = functionClass.info.decl(nme.apply)
+ val specializedApply = specializeTypes.specializedOverloaded(genericApply, exitingSpecialize(clazz.info.baseType(functionClass).typeArgs))
+ val app = Apply(gen.mkAttributedSelect(gen.mkAttributedThis(clazz), specializedApply), vparamss.head.map(p => gen.mkAttributedIdent(p.symbol)))
+ dd.symbol.setFlag(Flags.JAVA_DEFAULTMETHOD)
+ copyDefDef(dd)(rhs = typedPos(tree.pos)(app))
+ } else {
+ tree
+ }
+ case dd @ DefDef(_, _, _, vparamss, _, EmptyTree) if sym.owner.isTrait =>
+ val isDeferred = enteringPhase(currentRun.erasurePhase.prev)(sym.isDeferred) // before lateDEFERRED
+ // TODO Duplicated with isImplementedStatically, at this point sym.owner is still the trait so the other method returns false.
+ val isImplementedStatically = sym.isMethod && !sym.isModule && !sym.hasFlag(ACCESSOR | SUPERACCESSOR)
+ if (!isDeferred && isImplementedStatically) {
+ val implSym = exitingMixin(implClass(sym.owner).info.member(sym.name))
+ sym.setFlag(Flags.JAVA_DEFAULTMETHOD)
+ val tree = Apply(staticRef(implSym), gen.mkAttributedCast(gen.mkAttributedThis(sym.owner), sym.owner.typeOfThis) :: vparamss.head.map(t => gen.mkAttributedRef(t.symbol)))
+ val app = exitingMixin(typedPos(tree.pos)(tree))
+ copyDefDef(dd)(rhs = app)
+ } else {
+ tree
+ }
+
case Apply(Select(qual, _), args) =>
/* Changes `qual.m(args)` where m refers to an implementation
* class method to Q.m(S, args) where Q is the implementation module of
@@ -1186,12 +1098,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
typedPos(tree.pos)(Apply(staticRef(target), transformSuper(qual) :: args))
}
- if (isStaticOnly(sym)) {
- // change calls to methods which are defined only in implementation
- // classes to static calls of methods in implementation modules
- staticCall(sym)
- }
- else qual match {
+// if (isStaticOnly(sym)) {
+// // change calls to methods which are defined only in implementation
+// // classes to static calls of methods in implementation modules
+// staticCall(sym)
+// }
+// else
+ qual match {
case Super(_, mix) =>
// change super calls to methods in implementation classes to static calls.
// Transform references super.m(args) as follows:
@@ -1227,22 +1140,23 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
case Select(Super(_, _), name) =>
tree
- case Select(qual, name) if sym.owner.isImplClass && !isStaticOnly(sym) =>
- assert(!sym.isMethod, "no method allowed here: %s%s %s".format(sym, sym.isImplOnly, sym.flagString))
- // refer to fields in some implementation class via an abstract
- // getter in the interface.
- val iface = toInterface(sym.owner.tpe).typeSymbol
- val ifaceGetter = sym getterIn iface
-
- if (ifaceGetter == NoSymbol) abort("No getter for " + sym + " in " + iface)
- else typedPos(tree.pos)((qual DOT ifaceGetter)())
-
- case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
- // assign to fields in some implementation class via an abstract
- // setter in the interface.
- def setter = lhs.symbol.setterIn(toInterface(lhs.symbol.owner.tpe).typeSymbol) setPos lhs.pos
-
- typedPos(tree.pos)((qual DOT setter)(rhs))
+// TODO
+// case Select(qual, name) if sym.owner.isImplClass && !isStaticOnly(sym) =>
+// assert(!sym.isMethod, "no method allowed here: %s%s %s".format(sym, sym.isImplOnly, sym.flagString))
+// // refer to fields in some implementation class via an abstract
+// // getter in the interface.
+// val iface = toInterface(sym.owner.tpe).typeSymbol
+// val ifaceGetter = sym getterIn iface
+//
+// if (ifaceGetter == NoSymbol) abort("No getter for " + sym + " in " + iface)
+// else typedPos(tree.pos)((qual DOT ifaceGetter)())
+//
+// case Assign(Apply(lhs @ Select(qual, _), List()), rhs) =>
+// // assign to fields in some implementation class via an abstract
+// // setter in the interface.
+// def setter = lhs.symbol.setterIn(toInterface(lhs.symbol.owner.tpe).typeSymbol) setPos lhs.pos
+//
+// typedPos(tree.pos)((qual DOT setter)(rhs))
case _ =>
tree
@@ -1250,7 +1164,8 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
/** The main transform method.
- * This performs pre-order traversal preTransform at mixin phase;
+ * This performs pre-order travers
+ * al preTransform at mixin phase;
* when coming back, it performs a postTransform at phase after.
*/
override def transform(tree: Tree): Tree = {
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 53a1347a48b..9be56ee1c56 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -303,15 +303,15 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
}
- def specializedFunctionName(sym: Symbol, args: List[Type]) = exitingSpecialize {
+ def specializedFunctionClass(sym: Symbol, args: List[Type]): Symbol = exitingSpecialize {
require(isFunctionSymbol(sym), sym)
val env: TypeEnv = TypeEnv.fromSpecialization(sym, args)
- specializedClass.get((sym, env)) match {
- case Some(x) =>
- x.name
- case None =>
- sym.name
- }
+ specializedClass.getOrElse((sym, env), sym)
+ }
+
+ def specializedOverloaded(sym: Symbol, args: List[Type]): Symbol = exitingSpecialize {
+ val env: TypeEnv = TypeEnv.fromSpecialization(sym.owner, args)
+ overloads(sym).find(_.matchesEnv(env)).map(_.sym).getOrElse(NoSymbol)
}
/** Return the specialized name of 'sym' in the given environment. It
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index a5fdbb51486..92f0800c171 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -257,7 +257,7 @@ trait Infer extends Checkable {
case NoSymbol if sym.isJavaDefined && context.unit.isJava => sym // don't try to second guess Java; see #4402
case sym1 => sym1
}
- // XXX So... what's this for exactly?
+ // Pre-name-hashing dependency tracking for incremental compilation in sbt.
if (context.unit.exists)
context.unit.depends += sym.enclosingTopLevelClass
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index f3856db552f..9c6a34461e6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -134,28 +134,35 @@ trait MethodSynthesis {
ImplicitClassWrapper(tree).createAndEnterSymbol()
}
+ // TODO: why is all this symbol creation disconnected from addDerivedTrees,
+ // which creates another list of Field/Getter/Setter factories???
def enterGetterSetter(tree: ValDef) {
val ValDef(mods, name, _, _) = tree
if (nme.isSetterName(name))
ValOrValWithSetterSuffixError(tree)
- tree.symbol = (
+ tree.symbol =
if (mods.isLazy) {
val lazyValGetter = LazyValGetter(tree).createAndEnterSymbol()
enterLazyVal(tree, lazyValGetter)
} else {
- if (mods.isPrivateLocal)
+ if (mods.isPrivateLocal && mods.isCaseAccessor)
PrivateThisCaseClassParameterError(tree)
- val getter = Getter(tree).createAndEnterSymbol()
+ val getter = Getter(tree)
+ val getterSym = getter.createAndEnterSymbol()
// Create the setter if necessary.
- if (mods.isMutable)
- Setter(tree).createAndEnterSymbol()
+ if (getter.needsSetter) {
+ val setterSym = Setter(tree).createAndEnterSymbol()
+ getterSym.referenced = setterSym
+ setterSym.referenced = getterSym
+ }
- // If abstract, the tree gets the getter's symbol. Otherwise, create a field.
- if (mods.isDeferred) getter setPos tree.pos
+ // Create a field if the getter requires storage, otherwise,
+ // the getter's abstract and the tree gets the getter's symbol.
+ if (getter.noFieldHere) getterSym setPos tree.pos
else enterStrictVal(tree)
}
- )
+
enterBeans(tree)
}
@@ -177,11 +184,11 @@ trait MethodSynthesis {
}
def addDerivedTrees(typer: Typer, stat: Tree): List[Tree] = stat match {
- case vd @ ValDef(mods, name, tpt, rhs) if !noFinishGetterSetter(vd) =>
+ case vd @ ValDef(mods, name, tpt, rhs) if deriveAccessors(vd) =>
// If we don't save the annotations, they seem to wander off.
val annotations = stat.symbol.initialize.annotations
val trees = (
- allValDefDerived(vd)
+ (Field(vd) :: standardAccessors(vd) ::: beanAccessors(vd))
map (acc => atPos(vd.pos.focus)(acc derive annotations))
filterNot (_ eq EmptyTree)
)
@@ -221,11 +228,14 @@ trait MethodSynthesis {
stat :: Nil
}
- def standardAccessors(vd: ValDef): List[DerivedFromValDef] = (
- if (vd.mods.isMutable && !vd.mods.isLazy) List(Getter(vd), Setter(vd))
- else if (vd.mods.isLazy) List(LazyValGetter(vd))
- else List(Getter(vd))
- )
+ def standardAccessors(vd: ValDef): List[DerivedFromValDef] =
+ if (vd.mods.isLazy) List(LazyValGetter(vd))
+ else {
+ val getter = Getter(vd)
+ if (getter.needsSetter) List(getter, Setter(vd))
+ else List(getter)
+ }
+
def beanAccessors(vd: ValDef): List[DerivedFromValDef] = {
val setter = if (vd.mods.isMutable) List(BeanSetter(vd)) else Nil
if (vd.symbol hasAnnotation BeanPropertyAttr)
@@ -234,15 +244,6 @@ trait MethodSynthesis {
BooleanBeanGetter(vd) :: setter
else Nil
}
- def allValDefDerived(vd: ValDef) = {
- val field = if (vd.mods.isDeferred || (vd.mods.isLazy && hasUnitType(vd.symbol))) Nil
- else List(Field(vd))
- field ::: standardAccessors(vd) ::: beanAccessors(vd)
- }
-
- // Take into account annotations so that we keep annotated unit lazy val
- // to get better error message already from the cps plugin itself
- def hasUnitType(sym: Symbol) = (sym.tpe.typeSymbol == UnitClass) && sym.tpe.annotations.isEmpty
/** This trait assembles what's needed for synthesizing derived methods.
* Important: Typically, instances of this trait are created TWICE for each derived
@@ -260,7 +261,6 @@ trait MethodSynthesis {
def name: TermName
/** The flags that are retained from the original symbol */
-
def flagsMask: Long
/** The flags that the derived symbol has in addition to those retained from
@@ -272,7 +272,10 @@ trait MethodSynthesis {
def completer(sym: Symbol): Type
/** The derived symbol. It is assumed that this symbol already exists and has been
- * entered in the parent scope when derivedSym is called */
+ * entered in the parent scope when derivedSym is called
+ * this derived symbol business is super shady -- we're creating them,
+ * so why do we need to look them up with setterIn/getterIn??
+ */
def derivedSym: Symbol
/** The definition tree of the derived symbol. */
@@ -284,8 +287,9 @@ trait MethodSynthesis {
def enclClass: Symbol
// Final methods to make the rest easier to reason about.
- final def mods = tree.mods
- final def basisSym = tree.symbol
+ final def mods = tree.mods
+ final def basisSym = tree.symbol
+ final def derivedMods = mods & flagsMask | flagsExtra
}
sealed trait DerivedFromClassDef extends DerivedFromMemberDef {
@@ -305,17 +309,27 @@ trait MethodSynthesis {
/* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
final def fieldSelection = Select(This(enclClass), basisSym)
- final def derivedMods: Modifiers = mods & flagsMask | flagsExtra mapAnnotations (_ => Nil)
def derivedSym: Symbol = tree.symbol
def derivedTree: Tree = EmptyTree
+ // No field for these vals:
+ // - abstract vals have no value we could store (until they become concrete, potentially)
+ // - a concrete val with a statically known value (Unit / ConstantType)
+ // performs its side effect according to lazy/strict semantics, but doesn't need to store its value
+ // each access will "evaluate" the RHS (a literal) again
+ // - concrete vals in traits don't yield a field here either (their getter's RHS has the initial value)
+ // Constructors will move the assignment to the constructor, abstracting over the field using the field setter,
+ // and Mixin will add a field to the class that mixes in the trait, implementing the accessors in terms of it
+ def noFieldHere = nothingToMemoize || owner.isTrait
+ protected def nothingToMemoize = isDeferred // TODO: we don't know the val's type at this point... || typeNeedsNoStorage(???)
+
def isSetter = false
def isDeferred = mods.isDeferred
def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
def validate() { }
- def createAndEnterSymbol(): Symbol = {
- val sym = owner.newMethod(name, tree.pos.focus, (tree.mods.flags & flagsMask) | flagsExtra)
+ def createAndEnterSymbol(): MethodSymbol = {
+ val sym = owner.newMethod(name, tree.pos.focus, derivedMods.flags)
setPrivateWithin(tree, sym)
enterInScope(sym)
sym setInfo completer(sym)
@@ -333,7 +347,12 @@ trait MethodSynthesis {
}
}
sealed trait DerivedGetter extends DerivedFromValDef {
- // TODO
+ // A getter obviously must be accompanied by a setter if the ValDef is mutable.
+ // We also need a setter for any val/var defined in a trait,
+ // since an interface in Java can't define a field,
+ // so we shall set the initial value indirectly in the trait's init method using the trait setter,
+ // which will be implemented in the class
+ def needsSetter = mods.isMutable || (owner.isTrait && !nothingToMemoize)
}
sealed trait DerivedSetter extends DerivedFromValDef {
override def isSetter = true
@@ -341,10 +360,13 @@ trait MethodSynthesis {
case (p :: Nil) :: _ => p
case _ => NoSymbol
}
- private def setterRhs = (
- if (mods.isDeferred || derivedSym.isOverloaded) EmptyTree
+ // TODO: when is `derivedSym.isOverloaded`??? is it always an error?
+ // `noFieldHere` does not imply DEFERRED (ask isDeferred if you must know)
+ // we automatically implement trait setters (where !isDeferred) in the subclass
+ private def setterRhs =
+ if (noFieldHere || derivedSym.isOverloaded) EmptyTree
else Assign(fieldSelection, Ident(setterParam))
- )
+
private def setterDef = DefDef(derivedSym, setterRhs)
override def derivedTree: Tree = if (setterParam == NoSymbol) EmptyTree else setterDef
}
@@ -363,8 +385,7 @@ trait MethodSynthesis {
context.error(tree.pos, s"Internal error: Unable to find the synthetic factory method corresponding to implicit class $name in $enclClass / ${enclClass.info.decls}")
result
}
- def derivedTree: DefDef =
- factoryMeth(mods & flagsMask | flagsExtra, name, tree)
+ def derivedTree: DefDef = factoryMeth(derivedMods, name, tree)
def flagsExtra: Long = METHOD | IMPLICIT | SYNTHETIC
def flagsMask: Long = AccessFlags
def name: TermName = tree.name.toTermName
@@ -385,8 +406,9 @@ trait MethodSynthesis {
}
}
case class Getter(tree: ValDef) extends BaseGetter(tree) {
- override def derivedSym = if (mods.isDeferred) basisSym else basisSym.getterIn(enclClass)
- private def derivedRhs = if (mods.isDeferred) EmptyTree else fieldSelection
+ override def derivedSym = if (isDeferred) basisSym else basisSym.getterIn(enclClass)
+ private def derivedRhs = if (noFieldHere) tree.rhs else fieldSelection
+
private def derivedTpt = {
// For existentials, don't specify a type for the getter, even one derived
// from the symbol! This leads to incompatible existentials for the field and
@@ -400,19 +422,21 @@ trait MethodSynthesis {
// Range position errors ensue if we don't duplicate this in some
// circumstances (at least: concrete vals with existential types.)
case ExistentialType(_, _) => TypeTree() setOriginal (tree.tpt.duplicate setPos tree.tpt.pos.focus)
- case _ if mods.isDeferred => TypeTree() setOriginal tree.tpt // keep type tree of original abstract field
+ case _ if isDeferred => TypeTree() setOriginal tree.tpt // keep type tree of original abstract field
case tp => TypeTree(tp)
}
tpt setPos tree.tpt.pos.focus
}
override def derivedTree: DefDef = newDefDef(derivedSym, derivedRhs)(tpt = derivedTpt)
}
+
/** Implements lazy value accessors:
- * - for lazy values of type Unit and all lazy fields inside traits,
- * the rhs is the initializer itself
- * - for all other lazy values z the accessor is a block of this form:
- * { z = ; z } where z can be an identifier or a field.
- */
+ * - for lazy values of type Unit and all lazy fields inside traits,
+ * the rhs is the initializer itself, because we'll just "compute" the result on every access
+ * ("computing" unit / constant type is free -- the side-effect is still only run once, using the init bitmap)
+ * - for all other lazy values z the accessor is a block of this form:
+ * { z = ; z } where z can be an identifier or a field.
+ */
case class LazyValGetter(tree: ValDef) extends BaseGetter(tree) {
class ChangeOwnerAndModuleClassTraverser(oldowner: Symbol, newowner: Symbol)
extends ChangeOwnerTraverser(oldowner, newowner) {
@@ -432,10 +456,9 @@ trait MethodSynthesis {
override def derivedTree: DefDef = {
val ValDef(_, _, tpt0, rhs0) = tree
val rhs1 = context.unit.transformed.getOrElse(rhs0, rhs0)
- val body = (
- if (tree.symbol.owner.isTrait || hasUnitType(basisSym)) rhs1
- else gen.mkAssignAndReturn(basisSym, rhs1)
- )
+ val body = if (noFieldHere) rhs1
+ else gen.mkAssignAndReturn(basisSym, rhs1)
+
derivedSym setPos tree.pos // cannot set it at createAndEnterSymbol because basisSym can possibly still have NoPosition
val ddefRes = DefDef(derivedSym, new ChangeOwnerAndModuleClassTraverser(basisSym, derivedSym)(body))
// ValDef will have its position focused whereas DefDef will have original correct rangepos
@@ -452,7 +475,7 @@ trait MethodSynthesis {
def flagsMask = SetterFlags
def flagsExtra = ACCESSOR
- override def derivedSym = basisSym.setterIn(enclClass)
+ override def derivedSym = basisSym.setterIn(enclClass, hasExpandedName = false)
}
case class Field(tree: ValDef) extends DerivedFromValDef {
def name = tree.localName
@@ -462,8 +485,9 @@ trait MethodSynthesis {
// By default annotations go to the field, except if the field is
// generated for a class parameter (PARAMACCESSOR).
override def keepClean = !mods.isParamAccessor
+
override def derivedTree = (
- if (mods.isDeferred) EmptyTree
+ if (noFieldHere) EmptyTree
else if (mods.isLazy) copyValDef(tree)(mods = mods | flagsExtra, name = this.name, rhs = EmptyTree).setPos(tree.pos.focus)
else copyValDef(tree)(mods = mods | flagsExtra, name = this.name)
)
@@ -501,12 +525,12 @@ trait MethodSynthesis {
// Derives a tree without attempting to use the original tree's symbol.
override def derivedTree = {
atPos(tree.pos.focus) {
- DefDef(derivedMods, name, Nil, ListOfNil, tree.tpt.duplicate,
+ DefDef(derivedMods mapAnnotations (_ => Nil), name, Nil, ListOfNil, tree.tpt.duplicate,
if (isDeferred) EmptyTree else Select(This(owner), tree.name)
)
}
}
- override def createAndEnterSymbol(): Symbol = enterSyntheticSym(derivedTree)
+ override def createAndEnterSymbol(): MethodSymbol = enterSyntheticSym(derivedTree).asInstanceOf[MethodSymbol]
}
case class BooleanBeanGetter(tree: ValDef) extends BeanAccessor("is") with AnyBeanGetter { }
case class BeanGetter(tree: ValDef) extends BeanAccessor("get") with AnyBeanGetter { }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4ad81b60aec..46ef76d896f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -118,18 +118,16 @@ trait Namers extends MethodSynthesis {
// PRIVATE | LOCAL are fields generated for primary constructor arguments
// @PP: ...or fields declared as private[this]. PARAMACCESSOR marks constructor arguments.
// Neither gets accessors so the code is as far as I know still correct.
- def noEnterGetterSetter(vd: ValDef) = !vd.mods.isLazy && (
- !owner.isClass
- || (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor)
- || (vd.name startsWith nme.OUTER)
- || (context.unit.isJava)
- || isEnumConstant(vd)
- )
+ // all lazy vals need accessors, even private[this]
+ // we can't emit fields in traits, so must add accessors
+ // TODO: this is duplicative with MethodSynthesis
+ def deriveAccessors(vd: ValDef) = vd.mods.isLazy || owner.isTrait || (owner.isClass && deriveAccessorsInClass(vd))
- def noFinishGetterSetter(vd: ValDef) = (
- (vd.mods.isPrivateLocal && !vd.mods.isLazy) // all lazy vals need accessors, even private[this]
- || vd.symbol.isModuleVar
- || isEnumConstant(vd))
+ def deriveAccessorsInClass(vd: ValDef) = !(
+ (vd.mods.isPrivateLocal && !vd.mods.isCaseAccessor)
+ || (vd.name startsWith nme.OUTER)
+ || vd.symbol.isModuleVar // ???
+ || isEnumConstant(vd))
/** Determines whether this field holds an enum constant.
* To qualify, the following conditions must be met:
@@ -655,14 +653,12 @@ trait Namers extends MethodSynthesis {
}
}
- def enterValDef(tree: ValDef) {
- if (noEnterGetterSetter(tree))
- assignAndEnterFinishedSymbol(tree)
- else
- enterGetterSetter(tree)
+ def enterValDef(vd: ValDef) {
+ if (!context.unit.isJava && deriveAccessors(vd)) enterGetterSetter(vd)
+ else assignAndEnterFinishedSymbol(vd)
- if (isEnumConstant(tree))
- tree.symbol setInfo ConstantType(Constant(tree.symbol))
+ if (isEnumConstant(vd))
+ vd.symbol setInfo ConstantType(Constant(vd.symbol))
}
def enterLazyVal(tree: ValDef, lazyAccessor: Symbol): TermSymbol = {
@@ -673,6 +669,7 @@ trait Namers extends MethodSynthesis {
// via "x$lzy" as can be seen in test #3927.
val sym = (
if (owner.isClass) createFieldSymbol(tree)
+ // TODO owner.isTrait
else owner.newValue(tree.name append nme.LAZY_LOCAL, tree.pos, (tree.mods.flags | ARTIFACT) & ~IMPLICIT)
)
enterValSymbol(tree, sym setFlag MUTABLE setLazyAccessor lazyAccessor)
diff --git a/src/library/scala/runtime/java8/JFunction.java b/src/library/scala/runtime/java8/JFunction.java
deleted file mode 100644
index 326aad3fecc..00000000000
--- a/src/library/scala/runtime/java8/JFunction.java
+++ /dev/null
@@ -1,146 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-import scala.runtime.BoxedUnit;
-
-public final class JFunction {
- private JFunction() {}
- public static scala.Function0 func(JFunction0 f) { return f; }
- public static scala.Function0 proc(JProcedure0 p) { return p; }
- public static scala.Function0 procSpecialized(JFunction0$mcV$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcB$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcS$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcI$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcJ$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcC$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcF$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcD$sp f) { return f; }
- public static scala.Function0 funcSpecialized(JFunction0$mcZ$sp f) { return f; }
- public static scala.Function1 func(JFunction1 f) { return f; }
- public static scala.Function1 proc(JProcedure1 p) { return p; }
- public static scala.Function1 procSpecialized(JFunction1$mcVI$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcZI$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcII$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcFI$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcJI$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcDI$sp f) { return f; }
- public static scala.Function1 procSpecialized(JFunction1$mcVJ$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcZJ$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcIJ$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcFJ$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcJJ$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcDJ$sp f) { return f; }
- public static scala.Function1 procSpecialized(JFunction1$mcVF$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcZF$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcIF$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcFF$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcJF$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcDF$sp f) { return f; }
- public static scala.Function1 procSpecialized(JFunction1$mcVD$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcZD$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcID$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcFD$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcJD$sp f) { return f; }
- public static scala.Function1 funcSpecialized(JFunction1$mcDD$sp f) { return f; }
- public static scala.Function2 func(JFunction2 f) { return f; }
- public static scala.Function2 proc(JProcedure2 p) { return p; }
- public static scala.Function2 procSpecialized(JFunction2$mcVII$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZII$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIII$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFII$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJII$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDII$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVIJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZIJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIIJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFIJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJIJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDIJ$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVID$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZID$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIID$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFID$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJID$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDID$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVJI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZJI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIJI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFJI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJJI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDJI$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVJJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZJJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIJJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFJJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJJJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDJJ$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVJD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZJD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIJD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFJD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJJD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDJD$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVDI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZDI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIDI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFDI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJDI$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDDI$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVDJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZDJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIDJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFDJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJDJ$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDDJ$sp f) { return f; }
- public static scala.Function2 procSpecialized(JFunction2$mcVDD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcZDD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcIDD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcFDD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcJDD$sp f) { return f; }
- public static scala.Function2 funcSpecialized(JFunction2$mcDDD$sp f) { return f; }
- public static scala.Function3 func(JFunction3 f) { return f; }
- public static scala.Function3 proc(JProcedure3 p) { return p; }
- public static scala.Function4 func(JFunction4 f) { return f; }
- public static scala.Function4 proc(JProcedure4 p) { return p; }
- public static scala.Function5 func(JFunction5 f) { return f; }
- public static scala.Function5 proc(JProcedure5 p) { return p; }
- public static scala.Function6 func(JFunction6 f) { return f; }
- public static scala.Function6 proc(JProcedure6 p) { return p; }
- public static scala.Function7 func(JFunction7 f) { return f; }
- public static scala.Function7 proc(JProcedure7 p) { return p; }
- public static scala.Function8 func(JFunction8 f) { return f; }
- public static scala.Function8 proc(JProcedure8 p) { return p; }
- public static scala.Function9 func(JFunction9 f) { return f; }
- public static scala.Function9 proc(JProcedure9 p) { return p; }
- public static scala.Function10 func(JFunction10 f) { return f; }
- public static scala.Function10 proc(JProcedure10 p) { return p; }
- public static scala.Function11 func(JFunction11 f) { return f; }
- public static scala.Function11 proc(JProcedure11 p) { return p; }
- public static scala.Function12 func(JFunction12 f) { return f; }
- public static scala.Function12 proc(JProcedure12 p) { return p; }
- public static scala.Function13 func(JFunction13 f) { return f; }
- public static scala.Function13 proc(JProcedure13 p) { return p; }
- public static scala.Function14 func(JFunction14 f) { return f; }
- public static scala.Function14 proc(JProcedure14 p) { return p; }
- public static scala.Function15 func(JFunction15 f) { return f; }
- public static scala.Function15 proc(JProcedure15 p) { return p; }
- public static scala.Function16 func(JFunction16 f) { return f; }
- public static scala.Function16 proc(JProcedure16 p) { return p; }
- public static scala.Function17 func(JFunction17 f) { return f; }
- public static scala.Function17 proc(JProcedure17 p) { return p; }
- public static scala.Function18 func(JFunction18 f) { return f; }
- public static scala.Function18 proc(JProcedure18 p) { return p; }
- public static scala.Function19 func(JFunction19 f) { return f; }
- public static scala.Function19 proc(JProcedure19 p) { return p; }
- public static scala.Function20 func(JFunction20 f) { return f; }
- public static scala.Function20 proc(JProcedure20 p) { return p; }
- public static scala.Function21 func(JFunction21 f) { return f; }
- public static scala.Function21 proc(JProcedure21 p) { return p; }
- public static scala.Function22 func(JFunction22 f) { return f; }
- public static scala.Function22 proc(JProcedure22 p) { return p; }
-}
-
diff --git a/src/library/scala/runtime/java8/JFunction0$mcB$sp.java b/src/library/scala/runtime/java8/JFunction0$mcB$sp.java
deleted file mode 100644
index c8827576300..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcB$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcB$sp extends JFunction0 {
- byte apply$mcB$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToByte(apply$mcB$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcC$sp.java b/src/library/scala/runtime/java8/JFunction0$mcC$sp.java
deleted file mode 100644
index c804529f718..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcC$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcC$sp extends JFunction0 {
- char apply$mcC$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToCharacter(apply$mcC$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcD$sp.java b/src/library/scala/runtime/java8/JFunction0$mcD$sp.java
deleted file mode 100644
index dacf50237c5..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcD$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcD$sp extends JFunction0 {
- double apply$mcD$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcD$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcF$sp.java b/src/library/scala/runtime/java8/JFunction0$mcF$sp.java
deleted file mode 100644
index 2a9f8249246..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcF$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcF$sp extends JFunction0 {
- float apply$mcF$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcF$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcI$sp.java b/src/library/scala/runtime/java8/JFunction0$mcI$sp.java
deleted file mode 100644
index 75c612f9165..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcI$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcI$sp extends JFunction0 {
- int apply$mcI$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcI$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java b/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java
deleted file mode 100644
index d08984c794c..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcJ$sp extends JFunction0 {
- long apply$mcJ$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJ$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcS$sp.java b/src/library/scala/runtime/java8/JFunction0$mcS$sp.java
deleted file mode 100644
index d9e36a39f0c..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcS$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcS$sp extends JFunction0 {
- short apply$mcS$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToShort(apply$mcS$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcV$sp.java b/src/library/scala/runtime/java8/JFunction0$mcV$sp.java
deleted file mode 100644
index abd5e6ebbe4..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcV$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcV$sp extends JFunction0 {
- void apply$mcV$sp();
-
- default Object apply() { apply$mcV$sp(); return scala.runtime.BoxedUnit.UNIT; }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java b/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java
deleted file mode 100644
index e1cd62a913b..00000000000
--- a/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0$mcZ$sp extends JFunction0 {
- boolean apply$mcZ$sp();
-
- default Object apply() { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZ$sp()); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction0.java b/src/library/scala/runtime/java8/JFunction0.java
deleted file mode 100644
index bdeb7d5f8e1..00000000000
--- a/src/library/scala/runtime/java8/JFunction0.java
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction0 extends scala.Function0 {
- default void $init$() {
- };
- default void apply$mcV$sp() {
- apply();
- }
- default byte apply$mcB$sp() {
- return scala.runtime.BoxesRunTime.unboxToByte(apply());
- }
- default short apply$mcS$sp() {
- return scala.runtime.BoxesRunTime.unboxToShort(apply());
- }
- default int apply$mcI$sp() {
- return scala.runtime.BoxesRunTime.unboxToInt(apply());
- }
- default long apply$mcJ$sp() {
- return scala.runtime.BoxesRunTime.unboxToLong(apply());
- }
- default char apply$mcC$sp() {
- return scala.runtime.BoxesRunTime.unboxToChar(apply());
- }
- default float apply$mcF$sp() {
- return scala.runtime.BoxesRunTime.unboxToFloat(apply());
- }
- default double apply$mcD$sp() {
- return scala.runtime.BoxesRunTime.unboxToDouble(apply());
- }
- default boolean apply$mcZ$sp() {
- return scala.runtime.BoxesRunTime.unboxToBoolean(apply());
- }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java
deleted file mode 100644
index 4fbb370b8bf..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcDD$sp extends JFunction1 {
- double apply$mcDD$sp(double v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java
deleted file mode 100644
index ce45666dd1d..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcDF$sp extends JFunction1 {
- double apply$mcDF$sp(float v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java
deleted file mode 100644
index 09cac947c96..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcDI$sp extends JFunction1 {
- double apply$mcDI$sp(int v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java
deleted file mode 100644
index f5154c3854e..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcDJ$sp extends JFunction1 {
- double apply$mcDJ$sp(long v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java
deleted file mode 100644
index 758b432d99b..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcFD$sp extends JFunction1 {
- float apply$mcFD$sp(double v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java
deleted file mode 100644
index 7e13e287a51..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcFF$sp extends JFunction1 {
- float apply$mcFF$sp(float v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java
deleted file mode 100644
index e3c4a203c78..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcFI$sp extends JFunction1 {
- float apply$mcFI$sp(int v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java
deleted file mode 100644
index d989fa1ea8e..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcFJ$sp extends JFunction1 {
- float apply$mcFJ$sp(long v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcID$sp.java b/src/library/scala/runtime/java8/JFunction1$mcID$sp.java
deleted file mode 100644
index bde5d88d463..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcID$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcID$sp extends JFunction1 {
- int apply$mcID$sp(double v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcID$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java
deleted file mode 100644
index d1d235aef11..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcIF$sp extends JFunction1 {
- int apply$mcIF$sp(float v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcII$sp.java b/src/library/scala/runtime/java8/JFunction1$mcII$sp.java
deleted file mode 100644
index ef44b3830cf..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcII$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.
- */
-
-package scala.runtime.java8;
-
-@FunctionalInterface
-public interface JFunction1$mcII$sp extends JFunction1 {
- int apply$mcII$sp(int v1);
-
- default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcII$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
-}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java
deleted file mode 100644
index 373d13cd46c..00000000000
--- a/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/*
- * Copyright (C) 2012-2015 Typesafe Inc.