|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
They both compile to INDY/MetaLambdaFactory, except when they
occur in a constructor call. (TODO: can we lift the ctor arg
expression to a method and avoid statically synthesizing
anonymous subclass altogether?)
Typers:
- no longer synthesize SAMs -- *adapt* a Function literal
to the expected (SAM/FunctionN) type
- Deal with polymorphic/existential sams (relevant tests:
pos/t8310, pos/t5099.scala, pos/t4869.scala) We know where
to find the result type, as all Function nodes have a
FunctionN-shaped type during erasure. (Including function
literals targeting a SAM type -- the sam type is tracked as
the *expected* type.)
Lift restriction on sam types being class types. It's enough
that they dealias to one, like regular instance creation
expressions.
Contexts:
- No longer need encl method hack for return in sam.
Erasure:
- erasure preserves SAM type for function nodes
- Normalize sam to erased function type during erasure,
otherwise we may box the function body from `$anonfun(args)`
to `{$anonfun(args); ()}` because the expected type for the
body is now `Object`, and thus `Unit` does not conform.
Delambdafy:
- must set static flag before calling createBoxingBridgeMethod
- Refactored `createBoxingBridgeMethod` to wrap my head around
boxing, reworked it to generalize from FunctionN's boxing
needs to arbitrary LMF targets.
Other refactorings: ThisReferringMethodsTraverser, TreeGen.
|
|
`typedFunction` uniformly recognizes Single Abstract Method types
and built-in `FunctionN` types, type checking literals regardless
of expected type.
`adapt` synthesizes an anonymous subclass of the SAM type, if
needed to meet the expected (non-`FunctionN`) type.
(Later, we may want to carry `Function` AST nodes with SAM types
through the whole pipeline until the back-end, and treat them
uniformly with built-in function types there too, emitting the
corresponding `invokedynamic` & `LambdaMetaFactory` bytecode.
Would be faster to avoid synthesizing all this code during type
checking...)
Refactor `typedFunction` for performance and clarity to avoid
non-local returns. A nice perk is that the error message for missing
argument types now indicates with `<error>` where they are missing
(see updated check file).
Allow pattern matching function literals when SAM type is expected
(SI-8429).
Support `return` in function body of SAM target type, by making the
synthetic `sam$body` method transparent to the `enclMethod` chain, so
that the `return` is interpreted in its original context.
A cleaner approach to inferring unknown type params of the SAM
method. Now that `synthesizeSAMFunction` operates on typed `Function`
nodes, we can take the types of the parameters and the body and
compare them against the function type that corresponds to the SAM
method's signature. Since we are reusing the typed body, we do need
to change owners for the symbols, and substitute the new method
argument symbols for the function's vparam syms.
Impl Notes:
- The shift from typing as a regular Function for SAM types was
triggered by limitation of the old approach, which deferred type
checking the body until it was in the synthetic SAM type
subclass, which would break if the expression was subsequently
retypechecked for implicit search. Other problems related to SAM
expansion in ctor args also are dodged now.
- Using `<:<`, not `=:=`, in comparing `pt`, as `=:=` causes
`NoInstance` exceptions when `WildcardType`s are encountered.
- Can't use method type subtyping: method arguments are in
invariant pos.
- Can't use STATIC yet, results in illegal bytecode. It would be a
better encoding, since the function body should not see members
of SAM class.
- This is all battle tested by running `synthesizeSAMFunction` on
all `Function` nodes while bootstrapping, including those where a
regular function type is expected. The only thing that didn't
work was regarding Function0 and the CBN transform, which breaks
outer path creation in lambdalift.
|