Boxing
Value members
Concrete methods
The following code:
The following code:
val f: Function1[Int, Any] = x => ...
results in the creation of a closure and an implementation method in the typer:
def $anonfun(x: Int): Any = ...
val f: Function1[Int, Any] = closure($anonfun)
Notice that $anonfun
takes a primitive as argument, but the SAM (Single Abstract Method)
of Function1
after erasure is:
def apply(x: Object): Object
which takes a reference as argument. Hence, some form of adaptation is required. The most reliable way to do this adaptation is to replace the closure implementation method by a bridge method that forwards to the original method with appropriate boxing/unboxing. For our example above, this would be:
def $anonfun$adapted(x: Object): Object = $anonfun(BoxesRunTime.unboxToInt(x))
val f: Function1 = closure($anonfun$adapted)
But in some situations we can avoid generating this bridge, either because the runtime can perform auto-adaptation, or because we can replace the closure functional interface by a specialized sub-interface, see comments in this method for details.
See test cases lambda-*.scala and t8017/ for concrete examples.
Adaptation of an expression e
to an expected type PT
, applying the following
rewritings exhaustively as long as the type of e
is not a subtype of PT
.
Adaptation of an expression e
to an expected type PT
, applying the following
rewritings exhaustively as long as the type of e
is not a subtype of PT
.
e -> e() if e
appears not as the function part of an application
e -> box(e) if e
is of erased value type
e -> unbox(e, PT) otherwise, if PT
is an erased value type
e -> box(e) if e
is of primitive type and PT
is not a primitive type
e -> unbox(e, PT) if PT
is a primitive type and e
is not of primitive type
e -> cast(e, PT) otherwise
Generate a synthetic cast operation from tree.tpe to pt. Does not do any boxing/unboxing (this is handled upstream). Casts from and to ErasedValueType are special, see the explanation in ExtensionMethods#transform.
Generate a synthetic cast operation from tree.tpe to pt. Does not do any boxing/unboxing (this is handled upstream). Casts from and to ErasedValueType are special, see the explanation in ExtensionMethods#transform.