Observation about nulls in type patterns
Brian Goetz
brian.goetz at oracle.com
Mon Jul 27 20:57:30 UTC 2020
> In the text above quoted from Jens Lideström, is some text missing in
> the third line?
I forwarded the complete mail, but perhaps his thoughts were incomplete....
>
> Presumably that latter could also be written as
>
> switch ((Number)(o.get1().get2())) {
> case Integer i: ...
> case Number n: …
> }
>
> and it might become a popular idiom always to provide that explicit
> cast in switch statements, and especially switch expressions, when
> there might be any doubt as to whether the switch has total coverage?
>
It could, and this would work when your brain-analysis was correct, but
would otherwise hide errors. The result of get2() has a dynamic type D,
and a static type S. If we cast to Number, we're asserting that D <:
Number; if this is not true, then we'll get a CCE at runtime. For code
that is control-flow dominated by the test, program analysis is free to
conclude the test succeeded (otherwise we'd not be executing that code),
so we can conclude that, if it ever runs, the last pattern is total and
the compiler can elide the dynamic test.
But this has the drawback that we might be wrong about what `get2()`
returns, and then it would CCE; presumably we are using type patterns in
switch to _avoid_ CCEs. If `get2` returns Object, and might return
something that is not a subtype of Number, the compiler won't balk
(Object is cast-convertible to Number), but we'll get a runtime error.
What we really want to do is assert that the _static_ return type of
`get2()` is a subtype of Number. And for that, the language provides
the obvious way to do that already:
Number n = o.get1().get2()
switch (n) { ... }
More information about the amber-spec-experts
mailing list