paulk-asert commented on PR #3164:
URL: https://github.com/apache/groovy/pull/3164#issuecomment-6588498663
Thanks Daniel, all three points confirmed and addressed.
**Generic method pointers.** `ToIntFunction<Long> f = P.&id`, `new P().&me`,
`use(P.&id)` and also `List.&first` (the type parameter from a class receiver)
are now "Possible loss of precision", as for `::`.
`ReturnConversionConsistencyTest` has a generic method pointer form (`G<T> g =
H.&id`), with the same `int->char` exception as the generic method reference.
I did it slightly differently from attaching `CLOSURE_ARGUMENTS`: the
functional interface's parameter types are used only to resolve the returned
type parameter, not to select among overloads. A method pointer is still a
`Closure` that picks its method at run time, so narrowing the candidates
statically could check a method other than the one called. For example, with
`static int f(Object o)` and `static long f(Long l)`, `ToIntFunction<Object> g
= C.&f` would pass as `f(Object)`, but `g.applyAsInt(5L)` calls `f(Long)` and
narrows its `long` silently. That case stays rejected, and there is a test for
it. `.&` is otherwise unchanged at run time, so `memoize()` and the like still
work under `@CompileStatic`.
**Docs.** The `char` wording now says `char` is not converted to a number
type, and only an `int` or a one-character string constant is converted to
`char`. That is the existing assignment rule, which this PR keeps; its oddities
(no range check for `int`, `Integer` rejected, the overlap with GROOVY-12620)
are in GROOVY-12648. The `Supplier<Byte> s = P::v` case is listed under "Now
rejected": it is the same rule a method's `return` (`Byte m() { P.v() }`)
already applies, and before, `s.get()` returned an `Integer`. The heading no
longer says "primitive".
**The equality test.** I've added a comment saying it has to come before the
erased branch and why.
**`null` unboxing.** I've kept `Boolean`/`Character` type arguments on the
metafactory as you suggested, but split the `null` behaviour into GROOVY-12647.
Probing every form shows the result already varies by form and mode in 6.0.0,
and this PR leaves it as it was:
| Returned `null` to | method `return` | `.&` / closure, any mode | lambda
dyn/TC | lambda CS | `::` dyn/TC | `::` CS |
|---|---|---|---|---|---|---|
| `boolean` (`Boolean`) | false | false | false | false | false | **NPE** |
| `int` (`Integer`) | NPE | GroovyCastException | GroovyCastException | NPE
| GroovyCastException | NPE |
| `char` (`Character`) | NPE | `'\0'` | `'\0'` | NPE | `'\0'` | NPE |
For `boolean`, the `@CompileStatic` method reference is the only form that
throws; even a `@CompileStatic` lambda gives `false`. For `char`, the
closure-based forms give `'\0'` while a method's `return` and the
`@CompileStatic` lambda and method reference throw. Making these agree involves
the closure conversion and the `@CompileStatic` lambda as well as the method
reference adapter, so it seemed better as its own change.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]