scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

A reflective call is generated while no reflective call warning is shown #10666

Open Atry opened 6 years ago

Atry commented 6 years ago
Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_152).
Type in expressions for evaluation. Or try :help.

scala> class Test {
     |   def byName(b: => Int): Int = b
     |   def testByNameFunction = {
     |     val namedFunction: ((=> Int) => Int) { def apply(i: => Int): Int } = byName _
     |     namedFunction(i = 1)
     |   }
     | }
defined class Test

scala> :javap Test
  Size 4008 bytes
  MD5 checksum 6e7ff33af14765e44b8ef3c2f0274734
  Compiled from "<console>"
public class $line3.$read$$iw$$iw$Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Utf8               $line3/$read$$iw$$iw$Test
    #2 = Class              #1            // $line3/$read$$iw$$iw$Test
    #3 = Utf8               java/lang/Object
    #4 = Class              #3            // java/lang/Object
    #5 = Utf8               <console>
    #6 = Utf8               $line3/$read$$iw$
    #7 = Class              #6            // $line3/$read$$iw$
    #8 = Utf8               $line3/$read
    #9 = Class              #8            // $line3/$read
   #10 = Utf8               $iw$
   #11 = Utf8               $line3/$read$$iw$$iw$
   #12 = Class              #11           // $line3/$read$$iw$$iw$
   #13 = Utf8               Test
   #14 = Utf8               java/lang/invoke/MethodHandles$Lookup
   #15 = Class              #14           // java/lang/invoke/MethodHandles$Lookup
   #16 = Utf8               java/lang/invoke/MethodHandles
   #17 = Class              #16           // java/lang/invoke/MethodHandles
   #18 = Utf8               Lookup
   #19 = Utf8               reflMethod$Method1
   #20 = Utf8               (Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #21 = Utf8               x$1
   #22 = Utf8               scala/runtime/StructuralCallSite
   #23 = Class              #22           // scala/runtime/StructuralCallSite
   #24 = Utf8               bootstrap
   #25 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #26 = NameAndType        #24:#25       // bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #27 = Methodref          #23.#26       // scala/runtime/StructuralCallSite.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #28 = MethodHandle       #6:#27        // invokestatic scala/runtime/StructuralCallSite.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
   #29 = Utf8               (Lscala/Function0;)Ljava/lang/Object;
   #30 = MethodType         #29           //  (Lscala/Function0;)Ljava/lang/Object;
   #31 = Utf8               apply
   #32 = Utf8               ()Lscala/runtime/StructuralCallSite;
   #33 = NameAndType        #31:#32       // apply:()Lscala/runtime/StructuralCallSite;
   #34 = InvokeDynamic      #0:#33        // #0:apply:()Lscala/runtime/StructuralCallSite;
   #35 = Utf8               find
   #36 = NameAndType        #35:#20       // find:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #37 = Methodref          #23.#36       // scala/runtime/StructuralCallSite.find:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #38 = Utf8               scala/runtime/ScalaRunTime$
   #39 = Class              #38           // scala/runtime/ScalaRunTime$
   #40 = Utf8               MODULE$
   #41 = Utf8               Lscala/runtime/ScalaRunTime$;
   #42 = NameAndType        #40:#41       // MODULE$:Lscala/runtime/ScalaRunTime$;
   #43 = Fieldref           #39.#42       // scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
   #44 = String             #31           // apply
   #45 = Utf8               parameterTypes
   #46 = Utf8               ()[Ljava/lang/Class;
   #47 = NameAndType        #45:#46       // parameterTypes:()[Ljava/lang/Class;
   #48 = Methodref          #23.#47       // scala/runtime/StructuralCallSite.parameterTypes:()[Ljava/lang/Class;
   #49 = Utf8               java/lang/Class
   #50 = Class              #49           // java/lang/Class
   #51 = Utf8               getMethod
   #52 = Utf8               (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #53 = NameAndType        #51:#52       // getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #54 = Methodref          #50.#53       // java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
   #55 = Utf8               ensureAccessible
   #56 = Utf8               (Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #57 = NameAndType        #55:#56       // ensureAccessible:(Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #58 = Methodref          #39.#57       // scala/runtime/ScalaRunTime$.ensureAccessible:(Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #59 = Utf8               add
   #60 = Utf8               (Ljava/lang/Class;Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #61 = NameAndType        #59:#60       // add:(Ljava/lang/Class;Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #62 = Methodref          #23.#61       // scala/runtime/StructuralCallSite.add:(Ljava/lang/Class;Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
   #63 = Utf8               methodCache1
   #64 = Utf8               Lscala/runtime/StructuralCallSite;
   #65 = Utf8               method1
   #66 = Utf8               Ljava/lang/reflect/Method;
   #67 = Utf8               Ljava/lang/Class;
   #68 = Utf8               java/lang/reflect/Method
   #69 = Class              #68           // java/lang/reflect/Method
   #70 = Utf8               byName
   #71 = Utf8               (Lscala/Function0;)I
   #72 = Utf8               b
   #73 = Utf8               scala/Function0
   #74 = Class              #73           // scala/Function0
   #75 = Utf8               apply$mcI$sp
   #76 = Utf8               ()I
   #77 = NameAndType        #75:#76       // apply$mcI$sp:()I
   #78 = InterfaceMethodref #74.#77       // scala/Function0.apply$mcI$sp:()I
   #79 = Utf8               this
   #80 = Utf8               L$line3/$read$$iw$$iw$Test;
   #81 = Utf8               Lscala/Function0;
   #82 = Utf8               testByNameFunction
   #83 = Utf8               java/lang/reflect/InvocationTargetException
   #84 = Class              #83           // java/lang/reflect/InvocationTargetException
   #85 = Utf8               java/lang/invoke/LambdaMetafactory
   #86 = Class              #85           // java/lang/invoke/LambdaMetafactory
   #87 = Utf8               altMetafactory
   #88 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #89 = NameAndType        #87:#88       // altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #90 = Methodref          #86.#89       // java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #91 = MethodHandle       #6:#90        // invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #92 = Utf8               (Ljava/lang/Object;)Ljava/lang/Object;
   #93 = MethodType         #92           //  (Ljava/lang/Object;)Ljava/lang/Object;
   #94 = Utf8               $anonfun$testByNameFunction$1$adapted
   #95 = Utf8               (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #96 = NameAndType        #94:#95       // $anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #97 = Methodref          #2.#96        // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #98 = MethodHandle       #6:#97        // invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #99 = Integer            7
  #100 = Integer            1
  #101 = Utf8               scala/Serializable
  #102 = Class              #101          // scala/Serializable
  #103 = Utf8               (L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
  #104 = NameAndType        #31:#103      // apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
  #105 = InvokeDynamic      #1:#104       // #1:apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
  #106 = Utf8               getClass
  #107 = Utf8               ()Ljava/lang/Class;
  #108 = NameAndType        #106:#107     // getClass:()Ljava/lang/Class;
  #109 = Methodref          #4.#108       // java/lang/Object.getClass:()Ljava/lang/Class;
  #110 = NameAndType        #19:#20       // reflMethod$Method1:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
  #111 = Methodref          #2.#110       // $line3/$read$$iw$$iw$Test.reflMethod$Method1:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
  #112 = MethodType         #76           //  ()I
  #113 = Utf8               $anonfun$testByNameFunction$2
  #114 = NameAndType        #113:#76      // $anonfun$testByNameFunction$2:()I
  #115 = Methodref          #2.#114       // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
  #116 = MethodHandle       #6:#115       // invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
  #117 = Integer            3
  #118 = Utf8               ()Lscala/runtime/java8/JFunction0$mcI$sp;
  #119 = NameAndType        #75:#118      // apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
  #120 = InvokeDynamic      #2:#119       // #2:apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
  #121 = Utf8               invoke
  #122 = Utf8               (Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
  #123 = NameAndType        #121:#122     // invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
  #124 = Methodref          #69.#123      // java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
  #125 = Utf8               getCause
  #126 = Utf8               ()Ljava/lang/Throwable;
  #127 = NameAndType        #125:#126     // getCause:()Ljava/lang/Throwable;
  #128 = Methodref          #84.#127      // java/lang/reflect/InvocationTargetException.getCause:()Ljava/lang/Throwable;
  #129 = Utf8               java/lang/Integer
  #130 = Class              #129          // java/lang/Integer
  #131 = Utf8               scala/runtime/BoxesRunTime
  #132 = Class              #131          // scala/runtime/BoxesRunTime
  #133 = Utf8               unboxToInt
  #134 = Utf8               (Ljava/lang/Object;)I
  #135 = NameAndType        #133:#134     // unboxToInt:(Ljava/lang/Object;)I
  #136 = Methodref          #132.#135     // scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
  #137 = Utf8               1
  #138 = Utf8               Ljava/lang/reflect/InvocationTargetException;
  #139 = Utf8               qual1
  #140 = Utf8               Lscala/Function1;
  #141 = Utf8               namedFunction
  #142 = Utf8               scala/Function1
  #143 = Class              #142          // scala/Function1
  #144 = Utf8               $anonfun$testByNameFunction$1
  #145 = Utf8               (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
  #146 = Utf8               $this
  #147 = NameAndType        #70:#71       // byName:(Lscala/Function0;)I
  #148 = Methodref          #2.#147       // $line3/$read$$iw$$iw$Test.byName:(Lscala/Function0;)I
  #149 = Utf8               <init>
  #150 = Utf8               ()V
  #151 = NameAndType        #149:#150     // "<init>":()V
  #152 = Methodref          #4.#151       // java/lang/Object."<init>":()V
  #153 = NameAndType        #144:#145     // $anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
  #154 = Methodref          #2.#153       // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
  #155 = Utf8               boxToInteger
  #156 = Utf8               (I)Ljava/lang/Integer;
  #157 = NameAndType        #155:#156     // boxToInteger:(I)Ljava/lang/Integer;
  #158 = Methodref          #132.#157     // scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  #159 = Utf8               $deserializeLambda$
  #160 = Utf8               (Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
  #161 = Utf8               scala/runtime/LambdaDeserialize
  #162 = Class              #161          // scala/runtime/LambdaDeserialize
  #163 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #164 = NameAndType        #24:#163      // bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #165 = Methodref          #162.#164     // scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #166 = MethodHandle       #6:#165       // invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #167 = Utf8               lambdaDeserialize
  #168 = NameAndType        #167:#160     // lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
  #169 = InvokeDynamic      #3:#168       // #3:lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
  #170 = Utf8               Code
  #171 = Utf8               LocalVariableTable
  #172 = Utf8               LineNumberTable
  #173 = Utf8               StackMapTable
  #174 = Utf8               MethodParameters
  #175 = Utf8               Signature
  #176 = Utf8               (Lscala/Function0<Ljava/lang/Object;>;)I
  #177 = Utf8               BootstrapMethods
  #178 = Utf8               SourceFile
  #179 = Utf8               InnerClasses
  #180 = Utf8               ScalaInlineInfo
  #181 = Utf8               Scala
{
  public static java.lang.reflect.Method reflMethod$Method1(java.lang.Class);
    descriptor: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=3, args_size=1
         0: invokedynamic #34,  0             // InvokeDynamic #0:apply:()Lscala/runtime/StructuralCallSite;
         5: astore_1
         6: aload_1
         7: aload_0
         8: invokevirtual #37                 // Method scala/runtime/StructuralCallSite.find:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
        11: astore_2
        12: aload_2
        13: ifnull        18
        16: aload_2
        17: areturn
        18: getstatic     #43                 // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
        21: aload_0
        22: ldc           #44                 // String apply
        24: aload_1
        25: invokevirtual #48                 // Method scala/runtime/StructuralCallSite.parameterTypes:()[Ljava/lang/Class;
        28: invokevirtual #54                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
        31: invokevirtual #58                 // Method scala/runtime/ScalaRunTime$.ensureAccessible:(Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
        34: astore_2
        35: aload_1
        36: aload_0
        37: aload_2
        38: invokevirtual #62                 // Method scala/runtime/StructuralCallSite.add:(Ljava/lang/Class;Ljava/lang/reflect/Method;)Ljava/lang/reflect/Method;
        41: pop
        42: aload_2
        43: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            5      39     1 methodCache1   Lscala/runtime/StructuralCallSite;
           11      33     2 method1   Ljava/lang/reflect/Method;
            0      44     0   x$1   Ljava/lang/Class;
      LineNumberTable:
        line 15: 0
      StackMapTable: number_of_entries = 1
        frame_type = 253 /* append */
          offset_delta = 18
          locals = [ class scala/runtime/StructuralCallSite, class java/lang/reflect/Method ]
    MethodParameters:
      Name                           Flags
      x$1                            final

  public int byName(scala.Function0<java.lang.Object>);
    descriptor: (Lscala/Function0;)I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=2
         0: aload_1
         1: invokeinterface #78,  1           // InterfaceMethod scala/Function0.apply$mcI$sp:()I
         6: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   L$line3/$read$$iw$$iw$Test;
            0       7     1     b   Lscala/Function0;
      LineNumberTable:
        line 12: 0
    Signature: #176                         // (Lscala/Function0<Ljava/lang/Object;>;)I
    MethodParameters:
      Name                           Flags
      b                              final

  public int testByNameFunction();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=6, locals=4, args_size=1
         0: aload_0
         1: invokedynamic #105,  0            // InvokeDynamic #1:apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
         6: astore_1
         7: aload_1
         8: astore_2
         9: aload_2
        10: invokevirtual #109                // Method java/lang/Object.getClass:()Ljava/lang/Class;
        13: invokestatic  #111                // Method reflMethod$Method1:(Ljava/lang/Class;)Ljava/lang/reflect/Method;
        16: aload_2
        17: iconst_1
        18: anewarray     #4                  // class java/lang/Object
        21: dup
        22: iconst_0
        23: invokedynamic #120,  0            // InvokeDynamic #2:apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
        28: aastore
        29: invokevirtual #124                // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
        32: goto          41
        35: astore_3
        36: aload_3
        37: invokevirtual #128                // Method java/lang/reflect/InvocationTargetException.getCause:()Ljava/lang/Throwable;
        40: athrow
        41: checkcast     #130                // class java/lang/Integer
        44: invokestatic  #136                // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
        47: ireturn
      Exception table:
         from    to  target type
             9    32    35   Class java/lang/reflect/InvocationTargetException
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           35       6     3     1   Ljava/lang/reflect/InvocationTargetException;
            8      36     2 qual1   Lscala/Function1;
            6      41     1 namedFunction   Lscala/Function1;
            0      48     0  this   L$line3/$read$$iw$$iw$Test;
      LineNumberTable:
        line 14: 0
        line 15: 7
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 35
          locals = [ class $line3/$read$$iw$$iw$Test, class scala/Function1, class scala/Function1 ]
          stack = [ class java/lang/reflect/InvocationTargetException ]
        frame_type = 69 /* same_locals_1_stack_item */
          stack = [ class java/lang/Object ]

  public static final int $anonfun$testByNameFunction$1($line3.$read$$iw$$iw$Test, scala.Function0);
    descriptor: (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: invokevirtual #148                // Method byName:(Lscala/Function0;)I
         5: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0 $this   L$line3/$read$$iw$$iw$Test;
            0       6     1     b   Lscala/Function0;
      LineNumberTable:
        line 14: 0
    MethodParameters:
      Name                           Flags
      $this                          final synthetic
      b                              final

  public static final int $anonfun$testByNameFunction$2();
    descriptor: ()I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_1
         1: ireturn
      LineNumberTable:
        line 15: 0

  public $line3.$read$$iw$$iw$Test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #152                // Method java/lang/Object."<init>":()V
         4: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   L$line3/$read$$iw$$iw$Test;
      LineNumberTable:
        line 19: 0
        line 11: 4

  public static final java.lang.Object $anonfun$testByNameFunction$1$adapted($line3.$read$$iw$$iw$Test, scala.Function0);
    descriptor: (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: invokestatic  #154                // Method $anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
         5: invokestatic  #158                // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
         8: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0 $this   L$line3/$read$$iw$$iw$Test;
            0       9     1     b   Lscala/Function0;
      LineNumberTable:
        line 14: 0
    MethodParameters:
      Name                           Flags
      $this                          final
      b                              final
}
BootstrapMethods:
  0: #28 invokestatic scala/runtime/StructuralCallSite.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #30 (Lscala/Function0;)Ljava/lang/Object;
  1: #91 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #93 (Ljava/lang/Object;)Ljava/lang/Object;
      #98 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
      #30 (Lscala/Function0;)Ljava/lang/Object;
      #99 7
      #100 1
      #102 scala/Serializable
      #100 1
      #30 (Lscala/Function0;)Ljava/lang/Object;
  2: #91 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #112 ()I
      #116 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
      #112 ()I
      #117 3
      #100 1
      #102 scala/Serializable
  3: #166 invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #98 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
      #116 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
SourceFile: "<console>"
InnerClasses:
     public static #10= #7 of #9; //$iw$=class $line3/$read$$iw$ of class $line3/$read
     public static #10= #12 of #7; //$iw$=class $line3/$read$$iw$$iw$ of class $line3/$read$$iw$
     public static #13= #2 of #12; //Test=class $line3/$read$$iw$$iw$Test of class $line3/$read$$iw$$iw$
     public static final #18= #15 of #17; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
Error: unknown attribute
  ScalaInlineInfo: length = 0x27
   01 00 00 07 00 5E 00 5F 01 00 90 00 91 01 00 71
   00 4C 01 00 95 00 96 00 00 46 00 47 00 00 13 00
   14 00 00 52 00 4C 00
Error: unknown attribute
  Scala: length = 0x0

Note that namedFunction(i = 1) is a reflective call, i.e. there is an invokevirtual to the java/lang/reflect/Method.invoke, while no reflective call warning is shown.

@sjrd said in https://github.com/scala-js/scala-js/issues/3232:

If you use an explicit function type, then scalac does not generate a reflective call. It regularly calls the method applyOO defined in Function1, so that works because AnonFunction1 implements exactly that method.

I am not sure why scalac generates a reflective call for the original snippet. But because it does that, it then clashes with the fact that we use AnonFunctionNs instead of full-blown anonymous classes.

Atry commented 6 years ago

As @sjrd pointed out, if the parameter is an explicit function, then no reflective call generated. This behavior is more efficient than the behavior of by-name parameter.

Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_152).
Type in expressions for evaluation. Or try :help.

scala> class Test {
     |   def byName(b: () => Int): Int = b()
     |   def testByNameFunction = {
     |     val namedFunction: ((() => Int) => Int) { def apply(i: () => Int): Int } = byName _
     |     namedFunction(i = () => 1)
     |   }
     | }
defined class Test

scala> :javap Test
  Size 2542 bytes
  MD5 checksum a29ad0d28926030d11a2d43b2eece24b
  Compiled from "<console>"
public class $line3.$read$$iw$$iw$Test
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Utf8               $line3/$read$$iw$$iw$Test
    #2 = Class              #1            // $line3/$read$$iw$$iw$Test
    #3 = Utf8               java/lang/Object
    #4 = Class              #3            // java/lang/Object
    #5 = Utf8               <console>
    #6 = Utf8               $line3/$read$$iw$
    #7 = Class              #6            // $line3/$read$$iw$
    #8 = Utf8               $line3/$read
    #9 = Class              #8            // $line3/$read
   #10 = Utf8               $iw$
   #11 = Utf8               $line3/$read$$iw$$iw$
   #12 = Class              #11           // $line3/$read$$iw$$iw$
   #13 = Utf8               Test
   #14 = Utf8               java/lang/invoke/MethodHandles$Lookup
   #15 = Class              #14           // java/lang/invoke/MethodHandles$Lookup
   #16 = Utf8               java/lang/invoke/MethodHandles
   #17 = Class              #16           // java/lang/invoke/MethodHandles
   #18 = Utf8               Lookup
   #19 = Utf8               byName
   #20 = Utf8               (Lscala/Function0;)I
   #21 = Utf8               b
   #22 = Utf8               scala/Function0
   #23 = Class              #22           // scala/Function0
   #24 = Utf8               apply$mcI$sp
   #25 = Utf8               ()I
   #26 = NameAndType        #24:#25       // apply$mcI$sp:()I
   #27 = InterfaceMethodref #23.#26       // scala/Function0.apply$mcI$sp:()I
   #28 = Utf8               this
   #29 = Utf8               L$line3/$read$$iw$$iw$Test;
   #30 = Utf8               Lscala/Function0;
   #31 = Utf8               testByNameFunction
   #32 = Utf8               java/lang/invoke/LambdaMetafactory
   #33 = Class              #32           // java/lang/invoke/LambdaMetafactory
   #34 = Utf8               altMetafactory
   #35 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #36 = NameAndType        #34:#35       // altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #37 = Methodref          #33.#36       // java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #38 = MethodHandle       #6:#37        // invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
   #39 = Utf8               (Ljava/lang/Object;)Ljava/lang/Object;
   #40 = MethodType         #39           //  (Ljava/lang/Object;)Ljava/lang/Object;
   #41 = Utf8               $anonfun$testByNameFunction$1$adapted
   #42 = Utf8               (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #43 = NameAndType        #41:#42       // $anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #44 = Methodref          #2.#43        // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #45 = MethodHandle       #6:#44        // invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
   #46 = Utf8               (Lscala/Function0;)Ljava/lang/Object;
   #47 = MethodType         #46           //  (Lscala/Function0;)Ljava/lang/Object;
   #48 = Integer            7
   #49 = Integer            1
   #50 = Utf8               scala/Serializable
   #51 = Class              #50           // scala/Serializable
   #52 = Utf8               apply
   #53 = Utf8               (L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
   #54 = NameAndType        #52:#53       // apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
   #55 = InvokeDynamic      #0:#54        // #0:apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
   #56 = MethodType         #25           //  ()I
   #57 = Utf8               $anonfun$testByNameFunction$2
   #58 = NameAndType        #57:#25       // $anonfun$testByNameFunction$2:()I
   #59 = Methodref          #2.#58        // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
   #60 = MethodHandle       #6:#59        // invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
   #61 = Integer            3
   #62 = Utf8               ()Lscala/runtime/java8/JFunction0$mcI$sp;
   #63 = NameAndType        #24:#62       // apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
   #64 = InvokeDynamic      #1:#63        // #1:apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
   #65 = Utf8               scala/Function1
   #66 = Class              #65           // scala/Function1
   #67 = NameAndType        #52:#39       // apply:(Ljava/lang/Object;)Ljava/lang/Object;
   #68 = InterfaceMethodref #66.#67       // scala/Function1.apply:(Ljava/lang/Object;)Ljava/lang/Object;
   #69 = Utf8               scala/runtime/BoxesRunTime
   #70 = Class              #69           // scala/runtime/BoxesRunTime
   #71 = Utf8               unboxToInt
   #72 = Utf8               (Ljava/lang/Object;)I
   #73 = NameAndType        #71:#72       // unboxToInt:(Ljava/lang/Object;)I
   #74 = Methodref          #70.#73       // scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
   #75 = Utf8               namedFunction
   #76 = Utf8               Lscala/Function1;
   #77 = Utf8               $anonfun$testByNameFunction$1
   #78 = Utf8               (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
   #79 = Utf8               $this
   #80 = NameAndType        #19:#20       // byName:(Lscala/Function0;)I
   #81 = Methodref          #2.#80        // $line3/$read$$iw$$iw$Test.byName:(Lscala/Function0;)I
   #82 = Utf8               <init>
   #83 = Utf8               ()V
   #84 = NameAndType        #82:#83       // "<init>":()V
   #85 = Methodref          #4.#84        // java/lang/Object."<init>":()V
   #86 = NameAndType        #77:#78       // $anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
   #87 = Methodref          #2.#86        // $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
   #88 = Utf8               boxToInteger
   #89 = Utf8               (I)Ljava/lang/Integer;
   #90 = NameAndType        #88:#89       // boxToInteger:(I)Ljava/lang/Integer;
   #91 = Methodref          #70.#90       // scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
   #92 = Utf8               $deserializeLambda$
   #93 = Utf8               (Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
   #94 = Utf8               scala/runtime/LambdaDeserialize
   #95 = Class              #94           // scala/runtime/LambdaDeserialize
   #96 = Utf8               bootstrap
   #97 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
   #98 = NameAndType        #96:#97       // bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
   #99 = Methodref          #95.#98       // scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #100 = MethodHandle       #6:#99        // invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
  #101 = Utf8               lambdaDeserialize
  #102 = NameAndType        #101:#93      // lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
  #103 = InvokeDynamic      #2:#102       // #2:lambdaDeserialize:(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
  #104 = Utf8               Code
  #105 = Utf8               LocalVariableTable
  #106 = Utf8               LineNumberTable
  #107 = Utf8               Signature
  #108 = Utf8               (Lscala/Function0<Ljava/lang/Object;>;)I
  #109 = Utf8               MethodParameters
  #110 = Utf8               BootstrapMethods
  #111 = Utf8               SourceFile
  #112 = Utf8               InnerClasses
  #113 = Utf8               ScalaInlineInfo
  #114 = Utf8               Scala
{
  public int byName(scala.Function0<java.lang.Object>);
    descriptor: (Lscala/Function0;)I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=2
         0: aload_1
         1: invokeinterface #27,  1           // InterfaceMethod scala/Function0.apply$mcI$sp:()I
         6: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   L$line3/$read$$iw$$iw$Test;
            0       7     1     b   Lscala/Function0;
      LineNumberTable:
        line 12: 0
    Signature: #108                         // (Lscala/Function0<Ljava/lang/Object;>;)I
    MethodParameters:
      Name                           Flags
      b                              final

  public int testByNameFunction();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: aload_0
         1: invokedynamic #55,  0             // InvokeDynamic #0:apply:(L$line3/$read$$iw$$iw$Test;)Lscala/Function1;
         6: astore_1
         7: aload_1
         8: invokedynamic #64,  0             // InvokeDynamic #1:apply$mcI$sp:()Lscala/runtime/java8/JFunction0$mcI$sp;
        13: invokeinterface #68,  2           // InterfaceMethod scala/Function1.apply:(Ljava/lang/Object;)Ljava/lang/Object;
        18: invokestatic  #74                 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
        21: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            6      15     1 namedFunction   Lscala/Function1;
            0      22     0  this   L$line3/$read$$iw$$iw$Test;
      LineNumberTable:
        line 14: 0
        line 15: 7

  public static final int $anonfun$testByNameFunction$1($line3.$read$$iw$$iw$Test, scala.Function0);
    descriptor: (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: invokevirtual #81                 // Method byName:(Lscala/Function0;)I
         5: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0 $this   L$line3/$read$$iw$$iw$Test;
            0       6     1     b   Lscala/Function0;
      LineNumberTable:
        line 14: 0
    MethodParameters:
      Name                           Flags
      $this                          final synthetic
      b                              final

  public static final int $anonfun$testByNameFunction$2();
    descriptor: ()I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_1
         1: ireturn
      LineNumberTable:
        line 15: 0

  public $line3.$read$$iw$$iw$Test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #85                 // Method java/lang/Object."<init>":()V
         4: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   L$line3/$read$$iw$$iw$Test;
      LineNumberTable:
        line 19: 0
        line 11: 4

  public static final java.lang.Object $anonfun$testByNameFunction$1$adapted($line3.$read$$iw$$iw$Test, scala.Function0);
    descriptor: (L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: invokestatic  #87                 // Method $anonfun$testByNameFunction$1:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)I
         5: invokestatic  #91                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
         8: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0 $this   L$line3/$read$$iw$$iw$Test;
            0       9     1     b   Lscala/Function0;
      LineNumberTable:
        line 14: 0
    MethodParameters:
      Name                           Flags
      $this                          final
      b                              final
}
BootstrapMethods:
  0: #38 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #40 (Ljava/lang/Object;)Ljava/lang/Object;
      #45 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
      #47 (Lscala/Function0;)Ljava/lang/Object;
      #48 7
      #49 1
      #51 scala/Serializable
      #49 1
      #47 (Lscala/Function0;)Ljava/lang/Object;
  1: #38 invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #56 ()I
      #60 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
      #56 ()I
      #61 3
      #49 1
      #51 scala/Serializable
  2: #100 invokestatic scala/runtime/LambdaDeserialize.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/CallSite;
    Method arguments:
      #45 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$1$adapted:(L$line3/$read$$iw$$iw$Test;Lscala/Function0;)Ljava/lang/Object;
      #60 invokestatic $line3/$read$$iw$$iw$Test.$anonfun$testByNameFunction$2:()I
SourceFile: "<console>"
InnerClasses:
     public static #10= #7 of #9; //$iw$=class $line3/$read$$iw$ of class $line3/$read
     public static #10= #12 of #7; //$iw$=class $line3/$read$$iw$$iw$ of class $line3/$read$$iw$
     public static #13= #2 of #12; //Test=class $line3/$read$$iw$$iw$Test of class $line3/$read$$iw$$iw$
     public static final #18= #15 of #17; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
Error: unknown attribute
  ScalaInlineInfo: length = 0x22
   01 00 00 06 00 29 00 2A 01 00 4D 00 4E 01 00 39
   00 19 01 00 52 00 53 00 00 13 00 14 00 00 1F 00
   19 00
Error: unknown attribute
  Scala: length = 0x0
Atry commented 6 years ago

The accidental reflective call is the root cause of #10334 and https://github.com/scala-js/scala-js/issues/3232.

Atry commented 6 years ago

According to @gzm0's example, if namedFunction is an AnyRef, then the reflective call warning is shown, as expected:

Welcome to Scala 2.12.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_152).
Type in expressions for evaluation. Or try :help.

scala> class Test {
     |   def byName(b: => Int): Int = b
     |   def testByNameFunction = {
     |     val namedFunction: AnyRef { def apply(i: => Int): Int } = byName _
     |     namedFunction(i = 1)
     |   }
     | }
<console>:15: warning: reflective access of structural type member method apply should be enabled
by making the implicit value scala.language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scaladoc for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
           namedFunction(i = 1)
           ^
defined class Test