diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-12-12 13:05:28 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-12-12 22:02:24 +1000 |
commit | 1ff714b83795bff6604ef39604511ed896a49eea (patch) | |
tree | e3bb84fafa393b1121b746778d6fa076c8fa6293 /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 3de1c0c56ee530f4e75533fc9e1909fe0cde31b5 (diff) | |
download | scala-1ff714b83795bff6604ef39604511ed896a49eea.tar.gz scala-1ff714b83795bff6604ef39604511ed896a49eea.tar.bz2 scala-1ff714b83795bff6604ef39604511ed896a49eea.zip |
Compiler support for JEP-193 VarHandle polymorphic signatures
VarHandles bring a host of new "polymorphic signature" methods to
the Java 9 standard library. This commit updates the way we detect
such methods to look at the absense/presense of the
`PolymorphicSignature` annotation, so as to include these (and any
future additions.)
When we see applications of such methods, we disable adaptation
of argument and return types.
Tested manually with JDK9-ea:
```
Welcome to Scala 2.12.2-20161208-165912-3de1c0c (Java HotSpot(TM) 64-Bit Server VM, Java 9-ea).
Type in expressions for evaluation. Or try :help.
scala> import java.lang.invoke._, scala.runtime.IntRef
import java.lang.invoke._
import scala.runtime.IntRef
scala> val varHandle = MethodHandles.lookup().in(classOf[IntRef]).findVarHandle(classOf[IntRef], "elem", classOf[Int]);
varHandle: java.lang.invoke.VarHandle = java.lang.invoke.VarHandleInts$FieldInstanceReadWrite@7112ce6
scala> varHandle.getAndSet(ref, 1): Int
res5: Int = 0
scala> varHandle.getAndSet(ref, 1): Int
res6: Int = 1
```
Inspecting bytecode shows the absense of box/unboxing:
```
object Test {
import java.lang.invoke._, scala.runtime.IntRef
val varHandle = MethodHandles.lookup().in(classOf[IntRef]).findVarHandle(classOf[IntRef], "elem", classOf[Int]);
def main(args: Array[String]): Unit = {
val i : Int = varHandle.getAndSet(IntRef.zero, 1)
}
}
```
```
public void main(java.lang.String[]);
Code:
0: aload_0
1: invokevirtual #28 // Method varHandle:()Ljava/lang/invoke/VarHandle;
4: invokestatic #34 // Method scala/runtime/IntRef.zero:()Lscala/runtime/IntRef;
7: iconst_1
8: invokevirtual #40 // Method java/lang/invoke/VarHandle.getAndSet:(Lscala/runtime/IntRef;I)I
11: istore_2
12: return
```
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index fc0a0368ab..e017c7d864 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3401,7 +3401,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // governed by a) the argument types and b) the expected type val args1 = typedArgs(args, forArgMode(fun, mode)) val pts = args1.map(_.tpe.deconst) - val clone = fun.symbol.cloneSymbol + val clone = fun.symbol.cloneSymbol.withoutAnnotations val cloneParams = pts map (pt => clone.newValueParameter(currentUnit.freshTermName()).setInfo(pt)) val resultType = if (isFullyDefined(pt)) pt else ObjectTpe clone.modifyInfo(mt => copyMethodType(mt, cloneParams, resultType)) |