diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-01-19 18:47:10 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-26 09:31:57 -0700 |
commit | 236d0e0db8b4c53837bd580e2b2022d86afde456 (patch) | |
tree | 897e8694338eb40cc1e54c3b0f0a1ccafd331866 /test/files/pos/sammy_implicit.scala | |
parent | 4f4fb45d7bc41564c3ba0483c5a663172e063994 (diff) | |
download | scala-236d0e0db8b4c53837bd580e2b2022d86afde456.tar.gz scala-236d0e0db8b4c53837bd580e2b2022d86afde456.tar.bz2 scala-236d0e0db8b4c53837bd580e2b2022d86afde456.zip |
Refactor typedFunction, rework synthesizeSAMFunction for sammy
`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.
Diffstat (limited to 'test/files/pos/sammy_implicit.scala')
-rw-r--r-- | test/files/pos/sammy_implicit.scala | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/test/files/pos/sammy_implicit.scala b/test/files/pos/sammy_implicit.scala new file mode 100644 index 0000000000..c9c2519bab --- /dev/null +++ b/test/files/pos/sammy_implicit.scala @@ -0,0 +1,10 @@ +abstract class SamImplicitConvert { + trait Fun[A, B] { def apply(a: A): B } + class Lst[T] + abstract class Str { def getBytes: Array[Int] } + def flatMap[B](f: Fun[Str, Lst[B]]): List[B] = ??? + + implicit def conv(xs: Array[Int]): Lst[Int] + + val encoded = flatMap (_.getBytes) +} |