diff options
4 files changed, 36 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 2d4269a3bc..4cf3bef939 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -55,6 +55,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions._ import Flags._ + private val inlineFunctionExpansion = settings.Ydelambdafy.value == "inline" + /** the name of the phase: */ val phaseName: String = "specialize" @@ -1318,7 +1320,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } private def isAccessible(sym: Symbol): Boolean = - (currentClass == sym.owner.enclClass) && (currentClass != targetClass) + if (currentOwner.isAnonymousFunction) { + if (inlineFunctionExpansion) devWarning("anonymous function made it to specialization even though inline expansion is set.") + false + } + else (currentClass == sym.owner.enclClass) && (currentClass != targetClass) private def shouldMakePublic(sym: Symbol): Boolean = sym.hasFlag(PRIVATE | PROTECTED) && (addressFields || !nme.isLocalName(sym.name)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 396f3407f3..69ae6ec0c8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -136,8 +136,8 @@ abstract class Duplicators extends Analyzer { sym private def invalidate(tree: Tree, owner: Symbol = NoSymbol) { - debuglog("attempting to invalidate " + tree.symbol) - if (tree.isDef && tree.symbol != NoSymbol) { + debuglog(s"attempting to invalidate symbol = ${tree.symbol}") + if ((tree.isDef || tree.isInstanceOf[Function]) && tree.symbol != NoSymbol) { debuglog("invalid " + tree.symbol) invalidSyms(tree.symbol) = tree @@ -166,6 +166,11 @@ abstract class Duplicators extends Analyzer { invalidateAll(tparams ::: vparamss.flatten) tree.symbol = NoSymbol + case Function(vparams, _) => + // invalidate parameters + invalidateAll(vparams) + tree.symbol = NoSymbol + case _ => tree.symbol = NoSymbol } @@ -226,6 +231,10 @@ abstract class Duplicators extends Analyzer { ddef.tpt modifyType fixType super.typed(ddef.clearType(), mode, pt) + case fun: Function => + debuglog("Clearing the type and retyping Function: " + fun) + super.typed(fun.clearType, mode, pt) + case vdef @ ValDef(mods, name, tpt, rhs) => // log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms) //if (mods.hasFlag(Flags.LAZY)) vdef.symbol.resetFlag(Flags.MUTABLE) // Martin to Iulian: lazy vars can now appear because they are no longer boxed; Please check that deleting this statement is OK. diff --git a/test/files/specialized/constant_lambda.check b/test/files/specialized/constant_lambda.check new file mode 100644 index 0000000000..4b095fd0ff --- /dev/null +++ b/test/files/specialized/constant_lambda.check @@ -0,0 +1,2 @@ +false +false diff --git a/test/files/specialized/constant_lambda.scala b/test/files/specialized/constant_lambda.scala new file mode 100644 index 0000000000..bb9a97403e --- /dev/null +++ b/test/files/specialized/constant_lambda.scala @@ -0,0 +1,16 @@ +// during development of late delmabdafying there was a problem where +// specialization would undo some of the work done in uncurry if the body of the +// lambda had a constant type. That would result in a compiler crash as +// when the delambdafy phase got a tree shape it didn't understand +class X[@specialized(Int) A] { + val f = { x: A => false } +} + +object Test { + def main(args: Array[String]) { + val xInt = new X[Int] + println(xInt.f(42)) + val xString = new X[String] + println(xString.f("hello")) + } +}
\ No newline at end of file |