Feedback wanted: switch expression typing
daniel.smith at oracle.com
Wed Mar 28 22:55:00 UTC 2018
> On Mar 28, 2018, at 4:17 PM, Liam Miller-Cushon <cushon at google.com> wrote:
> Hi Dan,
> On Wed, Mar 28, 2018 at 12:38 PM Dan Smith <daniel.smith at oracle.com <mailto:daniel.smith at oracle.com>> wrote:
> If you're able to build OpenJDK with this patch and run it on some real-world code, I'd appreciate any insights about what you find.
> I recorded the number of times each diagnostic was produced as a fraction of all conditional expressions in Google's codebase:
> compiler.note.primitive.conditional.incompatible - 1 in 1400
> compiler.note.primitive.conditional.box - 1 in 2400
> compiler.note.primitive.conditional.null - 1 in 700
> compiler.note.primitive.conditional.precision - 1 in 21000
> compiler.note.primitive.conditional.overload - 1 in 6800
> We've found that some fraction of the null / boxing cases are actually mistakes where the programmer expected the
> behaviour they would have gotten from target typing. We've been steering people away from relying on that behaviour
> with static analysis, so my numbers may under-count those diagnostics relative to other codebases.
Thanks! This is really useful.
Subjectively, big picture: how concerned would you be about changing typing rules in these cases?
Some followup questions, if you're able to dig into the specific cases and offer a sense of what they look like (if it helps, I could probably also improve the automated detection, with some feedback from you about what you're seeing):
1) The incompatibilities are maybe the biggest concern. And it's not clear that it's helpful for the compiler to reject these sorts of conversions, so maybe we should change the rules.
In particular, this is silly:
Short s = 0; // fine
Long l = 0; // error
So: what portion of "primitive.conditional.incompatible" are something other than a literal? Other than a constant expression?
2) Often, the choice of box class doesn't matter (e.g., if printing a Byte/Short/Integer/Long as a string). What portion of "primitive.conditional.box" seem to care about the which box class is chosen?
3) A common pattern for null checking is:
Integer ibox2 = (ibox == null) ? 0 : ibox;
I'm guessing many of your "primitive.conditional.null" cases look like that. And if not, they're likely to guarantee in the surrounding context that no nulls are present. What portion of these actually seem to need and expect a null pointer check?
4) The overload resolution test casts a somewhat wide net, because actually simulating overload resolution is complicated. So the test is looking for cases in which there are other candidates that would be considered. What portion of these invocations actually appear that they would prompt a different overload choice or an ambiguity? And if the resolved method changes, how often is it a behaviorally significant change (often different overloads have the same behavior)?
More information about the amber-spec-observers