Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
cb5daf3
SI-9665 Backquoted vbar in extractor pattern
som-snytt Feb 21, 2016
5fd8483
Added applyOrElse to MapLike
kilotaras Mar 20, 2016
9ec6278
SI-9760 Fix for higher-kinded GADT refinement
milessabin Apr 19, 2016
fa65623
Added missing result type to test.
milessabin Apr 20, 2016
5faad77
Added pos test with multiple cases; added neg tests.
milessabin May 6, 2016
b58634e
Improves the test cases for the scala-concurrent-tck
viktorklang Apr 5, 2016
45e607d
SI-9361 fixed assert allowing display of improved error message.
milessabin May 14, 2016
139f9a0
Make Range.Partial a value class
xuwei-k May 17, 2016
883fdd7
SI-5463 Check .jars before using them
May 10, 2016
214ea82
SI-9656 Range.toString distinguishes Numeric step
Feb 27, 2016
3cddeaa
SI-7916: ScriptEngine support
som-snytt Sep 14, 2015
80d996b
Include missing web assets in scaladoc
jodersky Apr 11, 2016
6be9fc6
SI-9781 Don't convert erroneous expression to assignment
liff May 19, 2016
481a390
Improvements to scala.concurrent.Future
viktorklang May 13, 2016
f7b575d
Merge pull request #5093 from jodersky/scaladoc-include-assets
szeiger May 20, 2016
72a59d9
Rename nsc.backend.jvm.CodeGenTools to testing.BytecodeTesting
lrytz May 19, 2016
5d5a6aa
Better abstraction for bytecode tests. Also organize some imports.
lrytz May 20, 2016
d9ce4dc
Better abstraction for JUnit run tests
lrytz May 20, 2016
ba510ab
Clean up bytecode testing methods.
lrytz May 20, 2016
0e7964a
Small cleanup in JUnit test
lrytz May 20, 2016
46d523b
Cleanup in BytecodeTest
lrytz May 20, 2016
2537027
Split RunTest and BytecodeTest into parts, put in matching packages.
lrytz May 20, 2016
64fdae8
All JUnit tests pass without bootstrap (when run in intellij, sbt)
lrytz May 20, 2016
e26835c
Adapt naming convention for collection.convert null safety test
lrytz May 20, 2016
1ea1916
Merge pull request #4819 from som-snytt/issue/7916-ScriptEngine-deferred
szeiger May 20, 2016
eeef260
SI-8044 Allow binding backquoted varid in patterns
som-snytt Jan 31, 2016
2eb1cc2
SI-8044 Test for quoted not-a-varid
som-snytt Jan 31, 2016
1e565d8
SI-8044 Allow any id in explicit pattern binding
som-snytt Mar 15, 2016
a79b9b7
Merge pull request #4988 from som-snytt/issue/backtick-bar
adriaanm May 21, 2016
2e40aa5
Merge pull request #5180 from lrytz/junit-pass
retronym May 23, 2016
093c934
SI-9776: Fix type of PriorityQueue.newBuilder and improve performance
chrisokasaki May 23, 2016
95f5760
Merge pull request #5168 from xuwei-k/range-value-class
lrytz May 23, 2016
03d2de2
SI-9121 test case (fixed in new optimizer), SI-9179 test case
lrytz Apr 25, 2016
8e92ba0
Merge pull request #5153 from petermz/ticket/5463
lrytz May 23, 2016
82d9551
Merge pull request #5162 from milessabin/t9361
lrytz May 23, 2016
7645c7f
Merge pull request #5122 from lrytz/t9121
szeiger May 23, 2016
90ca3fd
Group Console and AnsiColor entities and add usage examples
janekdb May 23, 2016
d169d48
Merge pull request #5173 from janekdb/topic/2.12.x-scaladoc-AnsiColour
lrytz May 23, 2016
095295a
Merge pull request #5164 from viktorklang/wip-future-docs-√
adriaanm May 23, 2016
755fff0
Merge pull request #5181 from chrisokasaki/issue/9776
adriaanm May 23, 2016
0659af2
Merge pull request #5106 from milessabin/topic/hkgadt
adriaanm May 24, 2016
207e32d
Merge pull request #5179 from liff/topic/SI-9781
adriaanm May 24, 2016
892a6d6
SI-2712 Add support for higher order unification
milessabin May 20, 2016
bf47808
-Xexperimental mode now only includes -Ypartial-unification
milessabin May 20, 2016
4d28084
Merge pull request #5175 from som-snytt/issue/9656-range-toString
szeiger May 24, 2016
60f28f9
SI-9522 release key reference when deleting from OpenHashMap
performantdata Apr 25, 2016
808f3d0
Merge pull request #4935 from som-snytt/issue/8044-tickvar
adriaanm May 24, 2016
dd3a90e
Fix Scaladoc link syntax on java.util.Formatter references
janekdb May 24, 2016
1db58b5
Debug flag to print a summary of the inliner's work
lrytz May 24, 2016
c17ef77
Merge pull request #5124 from performantdata/bug/SI-9522
lrytz May 25, 2016
eaefb10
Merge pull request #5185 from janekdb/topic/2.12.x-scaladoc-java-link…
lrytz May 25, 2016
734c5ad
Merge pull request #5052 from kilotaras/topic/map-applyOrElse
lrytz May 25, 2016
450df0e
Use full braces style in AnsiColor example
janekdb May 25, 2016
65642d9
Merge pull request #5188 from janekdb/topic/2.12.x-scaladoc-AnsiColour-2
lrytz May 25, 2016
b85c9a7
Rename -Yopt to -opt, -Yopt-warnings to -opt-warnings
lrytz May 25, 2016
54dff81
SI-9382 Privatize enhanced x in Tuple2Zipped.Ops
som-snytt May 25, 2016
3873fcf
Fully qualify types in REPL generated code
dwijnand May 24, 2016
edbf2c4
Merge pull request #5189 from lrytz/y-not
adriaanm May 26, 2016
0b79f4b
SI-9382 Zippy clean-up in aisle 2 & 3
som-snytt May 26, 2016
fd6386a
SI-9794 Error advice uses decoded method name
som-snytt May 27, 2016
a09ed48
Merge pull request #5192 from dwijnand/wip/scala-repl-no-imports
retronym May 27, 2016
79ec0f3
Merge pull request #5186 from lrytz/inlinerM5
retronym May 27, 2016
6b2037a
Merge pull request #5102 from milessabin/2.12.x
retronym May 27, 2016
981e3c5
SI-9483 Add `since` to `@deprecatedName`
soc Apr 2, 2016
673350e
SI-9084 Add `since` (if available) to deprecation warnings
soc Apr 2, 2016
5562e1a
Lower-case spelling of @deprecated messages
soc May 19, 2016
be38ebb
Add since arg to deprecationWarning and use it
soc Apr 2, 2016
85057d5
Add documentation to @deprecated
soc May 19, 2016
a45509c
Don't pass -opt to starr / locker build in the bootstrap script
lrytz May 30, 2016
6265eb8
Merge pull request #5200 from lrytz/bootstrap-opt-options
lrytz May 30, 2016
7d5a0b3
Merge pull request #5193 from som-snytt/issue/9794
lrytz May 30, 2016
9edbe3d
Merge pull request #5191 from som-snytt/issue/9382
lrytz May 30, 2016
8f567bc
Merge pull request #5076 from soc/topic/deprecations-since
lrytz May 30, 2016
7b132f3
Avoid tree sharing with substituteThis
retronym May 31, 2016
0533a3d
Lambda impl methods static and more stably named
retronym May 4, 2016
f01d061
Treat self parameter as non-null in the optimizer
lrytz May 13, 2016
7a589e0
Remove nonsensical body for trait getter
retronym May 19, 2016
b33e4a0
Better diagnostic for optimizer crashes
retronym May 9, 2016
f882d16
Remove stray .class file from version control
retronym May 31, 2016
c61795a
Don't minimize parents of java defined syms.
retronym May 31, 2016
4499c32
Revert pruning of redundant Java parents
retronym May 17, 2016
0cb67d1
clear all flags when resetting a symbol
lrytz May 25, 2016
e82e457
SI-9256 check companions in same compilation unit only if same run
lrytz May 25, 2016
e791790
Emit trait method bodies in statics
retronym May 4, 2016
3787426
Add impl restriction related to invokespecial to Java parents
retronym May 5, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Lambda impl methods static and more stably named
The body of lambdas is compiled into a synthetic method
in the enclosing class. Previously, this method was a public
virtual method named `fully$qualified$Class$$anonfun$n`.
For lambdas that didn't capture a `this` reference, a static
method was used.

This commit changes two aspects.

Firstly, all lambda impl methods are now emitted static.
An extra parameter is added to those that require a this
reference.

This is an improvement as it:

  - allows, shorter, more readable names for the lambda impl method
  - avoids pollution of the vtable of the class. Note that javac uses
    private instance methods, rather than public static methods. If
    we followed its lead, we would be unable to support important use
    cases in our inliner

Secondly, the name of the enclosing method has been included in
the name of the lambda impl method to improve debuggability and
to improve serialization compatibility. The serialization improvement
comes from the way that fresh names for the impl methods are
allocated: adding or removing lambdas in methods not named "foo" won't
change the numbering of the `anonfun$foo$n` impl methods from methods
named "foo". This is in line with user expectations about anonymous
class and lambda serialization stability. Brian Goetz has described
this tricky area well in:

  http://cr.openjdk.java.net/~briangoetz/eg-attachments/lambda-serialization.html

This commit doesn't go as far a Javac, we don't use the hash of the
lambda type info, param names, etc to map to a lambda impl method name.
As such, we are more prone to the type-1 and -2 failures described there.
However, our Scala 2.11.8 has similar characteristics, so we aren't going
backwards.

Special case in the naming: Use "new" rather than "<init>" for constructor enclosed
lambdas, as javac does.

I have also changed the way that "delambdafy target" methods are identifed.
Rather than relying on the naming convention, I have switched to using a
symbol attachment. The assumption is that we only need to identify them
from within the same compilation unit.

This means we can distinguish impl metbods for expanded functions
(ones called from an `apply` method of an ahead-of-time expanded
anonfun class), from those that truly end up as targets for lambda
metafactory. Only the latter are translated to static methods in
this patch.
  • Loading branch information
retronym committed Jun 1, 2016
commit 0533a3df71e9c855ac68e10d060c2c87d16994e0
50 changes: 47 additions & 3 deletions src/compiler/scala/tools/nsc/ast/TreeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
* (outside the synchronized block).
*
* The idiom works only if the condition is using a volatile field.
* @see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
*
* @see http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
*/
def mkSynchronizedCheck(clazz: Symbol, cond: Tree, syncBody: List[Tree], stats: List[Tree]): Tree =
mkSynchronizedCheck(mkAttributedThis(clazz), cond, syncBody, stats)
Expand Down Expand Up @@ -274,8 +275,19 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
}

// used to create the lifted method that holds a function's body
def mkLiftedFunctionBodyMethod(localTyper: analyzer.Typer)(owner: Symbol, fun: Function) =
mkMethodForFunctionBody(localTyper)(owner, fun, nme.ANON_FUN_NAME)(additionalFlags = ARTIFACT)
def mkLiftedFunctionBodyMethod(localTyper: global.analyzer.Typer)(owner: global.Symbol, fun: global.Function) = {
def nonLocalEnclosingMember(sym: Symbol): Symbol = {
if (sym.isLocalDummy) sym.enclClass.primaryConstructor
else if (sym.isLocalToBlock) nonLocalEnclosingMember(sym.originalOwner)
else sym
}
val ownerName = nonLocalEnclosingMember(fun.symbol.originalOwner).name match {
case nme.CONSTRUCTOR => nme.NEWkw // do as javac does for the suffix, prefer "new" to "$lessinit$greater$1"
case x => x
}
val newName = nme.ANON_FUN_NAME.append(nme.NAME_JOIN_STRING).append(ownerName)
mkMethodForFunctionBody(localTyper)(owner, fun, newName)(additionalFlags = ARTIFACT)
}


/**
Expand Down Expand Up @@ -310,6 +322,38 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
newDefDef(methSym, moveToMethod(useMethodParams(fun.body)))(tpt = TypeTree(resTp))
}

/**
* Create a new `DefDef` based on `orig` with an explicit self parameter.
*
* Details:
* - Must by run after erasure
* - If `maybeClone` is the identity function, this runs "in place"
* and mutates the symbol of `orig`. `orig` should be discarded
* - Symbol owners and returns are substituted, as are parameter symbols
* - Recursive calls are not rewritten. This is correct if we assume
* that we either:
* - are in "in-place" mode, but can guarantee that no recursive calls exists
* - are associating the RHS with a cloned symbol, but intend for the original
* method to remain and for recursive calls to target it.
*/
final def mkStatic(orig: DefDef, maybeClone: Symbol => Symbol): DefDef = {
assert(phase.erasedTypes, phase)
assert(!orig.symbol.hasFlag(SYNCHRONIZED), orig.symbol.defString)
val origSym = orig.symbol
val origParams = orig.symbol.info.params
val newSym = maybeClone(orig.symbol)
newSym.setFlag(STATIC)
// Add an explicit self parameter
val selfParamSym = newSym.newSyntheticValueParam(newSym.owner.typeConstructor, nme.SELF)
newSym.updateInfo(newSym.info match {
case mt @ MethodType(params, res) => copyMethodType(mt, selfParamSym :: params, res)
})
val selfParam = ValDef(selfParamSym)
val rhs = orig.rhs.substituteThis(newSym.owner, atPos(newSym.pos)(gen.mkAttributedIdent(selfParamSym)))
.substituteSymbols(origParams, newSym.info.params.drop(1)).changeOwner(origSym -> newSym)
treeCopy.DefDef(orig, orig.mods, orig.name, orig.tparams, (selfParam :: orig.vparamss.head) :: Nil, orig.tpt, rhs).setSymbol(newSym)
}

// TODO: the rewrite to AbstractFunction is superfluous once we compile FunctionN to a SAM type (aka functional interface)
def functionClassType(fun: Function): Type =
if (isFunctionType(fun.tpe)) abstractFunctionType(fun.vparams.map(_.symbol.tpe), fun.body.tpe.deconst)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {

def getBoxedUnit: FieldInsnNode = new FieldInsnNode(GETSTATIC, srBoxedUnitRef.internalName, "UNIT", srBoxedUnitRef.descriptor)

private val anonfunAdaptedName = """.*\$anonfun\$\d+\$adapted""".r
private val anonfunAdaptedName = """.*\$anonfun\$.*\$\d+\$adapted""".r
def hasAdaptedImplMethod(closureInit: ClosureInstantiation): Boolean = {
isBuiltinFunctionType(Type.getReturnType(closureInit.lambdaMetaFactoryCall.indy.desc).getInternalName) &&
anonfunAdaptedName.pattern.matcher(closureInit.lambdaMetaFactoryCall.implMethod.getName).matches
Expand Down
29 changes: 21 additions & 8 deletions src/compiler/scala/tools/nsc/transform/Delambdafy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,18 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre

private def mkLambdaMetaFactoryCall(fun: Function, target: Symbol, functionalInterface: Symbol, samUserDefined: Symbol, isSpecialized: Boolean): Tree = {
val pos = fun.pos
def isSelfParam(p: Symbol) = p.isSynthetic && p.name == nme.SELF
val hasSelfParam = isSelfParam(target.firstParam)

val allCapturedArgRefs = {
// find which variables are free in the lambda because those are captures that need to be
// passed into the constructor of the anonymous function class
val captureArgs = FreeVarTraverser.freeVarsOf(fun).iterator.map(capture =>
gen.mkAttributedRef(capture) setPos pos
).toList

if (target hasFlag STATIC) captureArgs // no `this` reference needed
if (!hasSelfParam) captureArgs.filterNot(arg => isSelfParam(arg.symbol))
else if (currentMethod.hasFlag(Flags.STATIC)) captureArgs
else (gen.mkAttributedThis(fun.symbol.enclClass) setPos pos) :: captureArgs
}

Expand Down Expand Up @@ -179,7 +183,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val numCaptures = targetParams.length - functionParamTypes.length
val (targetCapturedParams, targetFunctionParams) = targetParams.splitAt(numCaptures)

val methSym = oldClass.newMethod(target.name.append("$adapted").toTermName, target.pos, target.flags | FINAL | ARTIFACT)
val methSym = oldClass.newMethod(target.name.append("$adapted").toTermName, target.pos, target.flags | FINAL | ARTIFACT | STATIC)
val bridgeCapturedParams = targetCapturedParams.map(param => methSym.newSyntheticValueParam(param.tpe, param.name.toTermName))
val bridgeFunctionParams =
map2(targetFunctionParams, bridgeParamTypes)((param, tp) => methSym.newSyntheticValueParam(tp, param.name.toTermName))
Expand Down Expand Up @@ -223,10 +227,8 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre

private def transformFunction(originalFunction: Function): Tree = {
val target = targetMethod(originalFunction)
target.makeNotPrivate(target.owner)

// must be done before calling createBoxingBridgeMethod and mkLambdaMetaFactoryCall
if (!(target hasFlag STATIC) && !methodReferencesThis(target)) target setFlag STATIC
assert(target.hasFlag(Flags.STATIC))
target.setFlag(notPRIVATE)

val funSym = originalFunction.tpe.typeSymbolDirect
// The functional interface that can be used to adapt the lambda target method `target` to the given function type.
Expand All @@ -252,11 +254,22 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// here's the main entry point of the transform
override def transform(tree: Tree): Tree = tree match {
// the main thing we care about is lambdas
case fun: Function => super.transform(transformFunction(fun))
case fun: Function =>
super.transform(transformFunction(fun))
case Template(_, _, _) =>
def pretransform(tree: Tree): Tree = tree match {
case dd: DefDef if dd.symbol.isDelambdafyTarget =>
if (!dd.symbol.hasFlag(STATIC) && methodReferencesThis(dd.symbol)) {
gen.mkStatic(dd, sym => sym)
} else {
dd.symbol.setFlag(STATIC)
dd
}
case t => t
}
try {
// during this call boxingBridgeMethods will be populated from the Function case
val Template(parents, self, body) = super.transform(tree)
val Template(parents, self, body) = super.transform(deriveTemplate(tree)(_.mapConserve(pretransform)))
Template(parents, self, body ++ boxingBridgeMethods)
} finally boxingBridgeMethods.clear()
case _ => super.transform(tree)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
class SpecializationDuplicator(casts: Map[Symbol, Type]) extends Duplicator(casts) {
override def retyped(context: Context, tree: Tree, oldThis: Symbol, newThis: Symbol, env: scala.collection.Map[Symbol, Type]): Tree =
enteringSpecialize(super.retyped(context, tree, oldThis, newThis, env))

}

/** A tree symbol substituter that substitutes on type skolems.
Expand Down
19 changes: 16 additions & 3 deletions src/compiler/scala/tools/nsc/transform/UnCurry.scala
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ abstract class UnCurry extends InfoTransform
// Expand the function body into an anonymous class
gen.expandFunction(localTyper)(fun, inConstructorFlag)
} else {
val mustExpand = mustExpandFunction(fun)
// method definition with the same arguments, return type, and body as the original lambda
val liftedMethod = gen.mkLiftedFunctionBodyMethod(localTyper)(fun.symbol.owner, fun)

Expand All @@ -221,11 +222,18 @@ abstract class UnCurry extends InfoTransform
gen.mkForwarder(gen.mkAttributedRef(liftedMethod.symbol), (fun.vparams map (_.symbol)) :: Nil)
))

if (!mustExpand) {
liftedMethod.symbol.updateAttachment(DelambdafyTarget)
liftedMethod.updateAttachment(DelambdafyTarget)
}

val typedNewFun = localTyper.typedPos(fun.pos)(Block(liftedMethod, super.transform(newFun)))
if (mustExpandFunction(fun)) {
if (mustExpand) {
val Block(stats, expr : Function) = typedNewFun
treeCopy.Block(typedNewFun, stats, gen.expandFunction(localTyper)(expr, inConstructorFlag))
} else typedNewFun
} else {
typedNewFun
}
}

def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = {
Expand Down Expand Up @@ -341,13 +349,18 @@ abstract class UnCurry extends InfoTransform

private def isSelfSynchronized(ddef: DefDef) = ddef.rhs match {
case Apply(fn @ TypeApply(Select(sel, _), _), _) =>
fn.symbol == Object_synchronized && sel.symbol == ddef.symbol.enclClass && !ddef.symbol.enclClass.isTrait
fn.symbol == Object_synchronized && sel.symbol == ddef.symbol.enclClass && !ddef.symbol.enclClass.isTrait &&
!ddef.symbol.isDelambdafyTarget /* these become static later, unsuitable for ACC_SYNCHRONIZED */
case _ => false
}

/** If an eligible method is entirely wrapped in a call to synchronized
* locked on the same instance, remove the synchronized scaffolding and
* mark the method symbol SYNCHRONIZED for bytecode generation.
*
* Delambdafy targets are deemed ineligible as the Delambdafy phase will
* replace `this.synchronized` with `$this.synchronzed` now that it emits
* all lambda impl methods as static.
*/
private def translateSynchronized(tree: Tree) = tree match {
case dd @ DefDef(_, _, _, _, _, Apply(fn, body :: Nil)) if isSelfSynchronized(dd) =>
Expand Down
7 changes: 6 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,12 @@ abstract class Duplicators extends Analyzer {

case ddef @ DefDef(_, _, _, _, tpt, rhs) =>
ddef.tpt modifyType fixType
super.typed(ddef.clearType(), mode, pt)
val result = super.typed(ddef.clearType(), mode, pt)
// TODO this is a hack, we really need a cleaner way to transport symbol attachments to duplicated methods
// bodies in specialized subclasses.
if (ddef.hasAttachment[DelambdafyTarget.type])
result.symbol.updateAttachment(DelambdafyTarget)
result

case fun: Function =>
debuglog("Clearing the type and retyping Function: " + fun)
Expand Down
2 changes: 2 additions & 0 deletions src/reflect/scala/reflect/internal/StdAttachments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ trait StdAttachments {
*/
case class SAMFunction(samTp: Type, sam: Symbol) extends PlainAttachment

case object DelambdafyTarget extends PlainAttachment

/** When present, indicates that the host `Ident` has been created from a backquoted identifier.
*/
case object BackquotedIdentifierAttachment extends PlainAttachment
Expand Down
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>

final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isDelambdafyFunction = isSynthetic && (name containsName tpnme.DELAMBDAFY_LAMBDA_CLASS_NAME)
final def isDelambdafyTarget = isArtifact && isMethod && (name containsName tpnme.ANON_FUN_NAME)
final def isDelambdafyTarget = isArtifact && isMethod && hasAttachment[DelambdafyTarget.type]
final def isDefinedInPackage = effectiveOwner.isPackageClass
final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass

Expand Down
1 change: 1 addition & 0 deletions src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.FixedMirrorTypeCreator
this.CompoundTypeTreeOriginalAttachment
this.SAMFunction
this.DelambdafyTarget
this.BackquotedIdentifierAttachment
this.ForAttachment
this.SyntheticUnitAttachment
Expand Down
8 changes: 4 additions & 4 deletions test/files/run/delambdafy_t6028.check
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ package <empty> {
def foo(methodParam: String): Function0 = {
val methodLocal: String = "";
{
(() => T.this.$anonfun$1(methodParam, methodLocal))
(() => T.this.$anonfun$foo$1(methodParam, methodLocal))
}
};
def bar(barParam: String): Object = {
Expand All @@ -21,10 +21,10 @@ package <empty> {
def tryy(tryyParam: String): Function0 = {
var tryyLocal: runtime.ObjectRef = scala.runtime.ObjectRef.create("");
{
(() => T.this.$anonfun$2(tryyParam, tryyLocal))
(() => T.this.$anonfun$tryy$1(tryyParam, tryyLocal))
}
};
final <artifact> private[this] def $anonfun$1(methodParam$1: String, methodLocal$1: String): String = T.this.classParam.+(T.this.field()).+(methodParam$1).+(methodLocal$1);
final <artifact> private[this] def $anonfun$foo$1(methodParam$1: String, methodLocal$1: String): String = T.this.classParam.+(T.this.field()).+(methodParam$1).+(methodLocal$1);
abstract trait MethodLocalTrait$1 extends Object {
def /*MethodLocalTrait$1*/$init$(barParam$1: String): Unit = {
()
Expand Down Expand Up @@ -54,7 +54,7 @@ package <empty> {
T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1)
else
MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]();
final <artifact> private[this] def $anonfun$2(tryyParam$1: String, tryyLocal$1: runtime.ObjectRef): Unit = try {
final <artifact> private[this] def $anonfun$tryy$1(tryyParam$1: String, tryyLocal$1: runtime.ObjectRef): Unit = try {
tryyLocal$1.elem = tryyParam$1
} finally ()
}
Expand Down
4 changes: 2 additions & 2 deletions test/files/run/delambdafy_t6555.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ package <empty> {
()
};
private[this] val f: String => String = {
final <artifact> def $anonfun(param: String): String = param;
((param: String) => $anonfun(param))
final <artifact> def $anonfun$f(param: String): String = param;
((param: String) => $anonfun$f(param))
};
<stable> <accessor> def f(): String => String = Foo.this.f
}
Expand Down
4 changes: 2 additions & 2 deletions test/files/run/delambdafy_uncurry_byname_method.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ package <empty> {
};
def bar(x: () => String): String = x.apply();
def foo(): String = Foo.this.bar({
final <artifact> def $anonfun(): String = "";
(() => $anonfun())
final <artifact> def $anonfun$foo(): String = "";
(() => $anonfun$foo())
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/files/run/delambdafy_uncurry_method.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ package <empty> {
};
def bar(): Unit = {
val f: Int => Int = {
final <artifact> def $anonfun(x: Int): Int = x.+(1);
((x: Int) => $anonfun(x))
final <artifact> def $anonfun|(x: Int): Int = x.+(1);
((x: Int) => $anonfun|(x))
};
()
}
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/t9097.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ object Test extends StoreReporterDirectTest {
assert(!storeReporter.hasErrors, message = filteredInfos map (_.msg) mkString "; ")
val out = baos.toString("UTF-8")
// was 2 before the fix, the two PackageDefs for a would both contain the ClassDef for the closure
assert(out.lines.count(_ contains "def $anonfun$1(x$1: Int): String") == 1, out)
assert(out.lines.count(_ contains "def $anonfun$hihi$1(x$1: Int): String") == 1, out)
}
}
2 changes: 1 addition & 1 deletion test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class IndySammyTest extends BytecodeTesting {
val c = compileClass(s"class C { ${lamDef(from, to, body)}; ${appDef(arg)} }", allowMessage = allowMessage)

val applySig = getAsmMethod(funClass, "apply").desc
val anonfun = getMethod(c, "C$$$anonfun$1")
val anonfun = getMethod(c, "$anonfun$lam$1")
val lamInsn = getInstructions(c, "lam").dropNonOp
val applyInvoke = getMethod(c, "app")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class OptimizedBytecodeTest extends BytecodeTesting {
val c = compileClass(code)

assertSameSummary(getMethod(c, "t"), List(
LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "C$$$anonfun$1", IRETURN))
assertSameSummary(getMethod(c, "C$$$anonfun$1"), List(LDC, "C$$$anonfun$2", IRETURN))
assertSameSummary(getMethod(c, "C$$$anonfun$2"), List(-1 /*A*/, GOTO /*A*/))
LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "$anonfun$t$1", IRETURN))
assertSameSummary(getMethod(c, "$anonfun$t$1"), List(ALOAD, IFNONNULL, ACONST_NULL, ATHROW, -1, LDC, "$anonfun$t$2", IRETURN))
assertSameSummary(getMethod(c, "$anonfun$t$2"), List(-1 /*A*/, GOTO /*A*/))
}

@Test
Expand Down Expand Up @@ -295,9 +295,9 @@ class OptimizedBytecodeTest extends BytecodeTesting {
|}
""".stripMargin
val c = compileClass(code, allowMessage = _.msg.contains("exception handler declared in the inlined method"))
assertInvoke(getMethod(c, "f1a"), "C", "C$$$anonfun$1")
assertInvoke(getMethod(c, "f1a"), "C", "$anonfun$f1a$1")
assertInvoke(getMethod(c, "f1b"), "C", "wrapper1")
assertInvoke(getMethod(c, "f2a"), "C", "C$$$anonfun$3")
assertInvoke(getMethod(c, "f2a"), "C", "$anonfun$f2a$1")
assertInvoke(getMethod(c, "f2b"), "C", "wrapper2")
}

Expand Down Expand Up @@ -331,7 +331,7 @@ class OptimizedBytecodeTest extends BytecodeTesting {
|class Listt
""".stripMargin
val List(c, nil, nilMod, listt) = compileClasses(code)
assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1")
assertInvoke(getMethod(c, "t"), "C", "$anonfun$t$1")
}

@Test
Expand All @@ -357,6 +357,6 @@ class OptimizedBytecodeTest extends BytecodeTesting {
def optimiseEnablesNewOpt(): Unit = {
val code = """class C { def t = (1 to 10) foreach println }"""
val List(c) = readAsmClasses(newCompiler(extraArgs = "-optimise -deprecation").compileToBytes(code, allowMessage = _.msg.contains("is deprecated")))
assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath
assertInvoke(getMethod(c, "t"), "C", "$anonfun$t$1") // range-foreach inlined from classpath
}
}
Loading