scala/scala — pull request #3037 by gkossakowski (2013-10-13 22:18:22+00:00)
Title: [resubmit] Experimental Single Abstract Method support (sammy meets world)

_This is resubmission of #3018 after merge conflict has been resolved._

Under `-Xexperimental`, `typedFunction` invokes `synthesizeSAMFunction` when the expected type for the function literal (`pt`) is not the built-in `FunctionN` type of the expected arity, but `pt` does have a SAM with the expected number of arguments.

`synthesizeSAMFunction` expands the following tree:

```
{ (p1: T1, ..., pN: TN) => body } : S
```

to:

```
{
def apply$body(p1: T1, ..., pN: TN): T = body

new S { def apply(p1: T1, ..., pN: TN): T = apply$body(p1,..., pN) }
}
```

The expansion assumes `S` (the expected type) defines a single abstract method (let's call that method `apply` for simplicity).

1. If `T` is not fully defined, it is inferred by type checking `def apply$body` without a result type before type checking the block. The method's inferred result type is used instead of `T`. [See test case](https://github.com/adriaanm/scala/blob/67062db57c1abef88e0049dac5d82d4f13375a48/test/files/pos/sammy_poly.scala)

2. To more easily enforce that `S`'s members are not in scope in `body`, that tree goes to the `apply$body` method that's outside the anonymous subclass of S. (The separate `apply$body` method simplifies the implementation of 1&2.) [See test case](https://github.com/adriaanm/scala/blob/67062db57c1abef88e0049dac5d82d4f13375a48/test/files/pos/sammy_scope.scala)

3. The following [restrictions](https://github.com/adriaanm/scala/commit/657e85fe2412cdadc5ee9dc348159b32dcdfcba7#diff-2b1bf15b53df94495f7155a69f822adeR727) apply to `S`:
1. Its primary constructor (if any) must be public, no-args, not overloaded.
2. S must have exactly one abstract member, its SAM
3. SAM must take exactly one argument list
4. SAM must be monomorphic

We may later relax these requirements to allow an implicit argument list, both on the constructor and the SAM. Could also let the SAM be polymorphic.

PS: We'll require `import language.sam` instead of `-Xexperimental`, as soon as the SIP is ready and there are more tests.