Patterns design question: Primitive type tests

Ali Ebrahimi ali.ebrahimi1781 at
Sun Nov 5 20:21:35 UTC 2017

I think expected behavior for matching targets should be consistent
with *Overload
Selection *in method call resolution phase. But in *Overload Selection *we
don't consider order of overload methods declaration in class file.

So with ordering in mind, I think match-test process should happen at most
in 4 step:
If step *i* don't match any case pattern we go to step *i+1, *otherwise we
found matched pattern and finished.

1) Without Boxing, Unboxing, Widening and Upcasting(can not do boxing,
unboxing, widening and upcasting)
2) Without Boxing, Unboxing and Upcasting but with Widening (can not do
boxing, unboxing and upcasting but can do widening)
3) With Boxing, Unboxing and Widening but without Upcasting(can do boxing,
unboxing and widening but can not do upcasting)
4) With Boxing, Unboxing, Widening and Upcasting(can do boxing, unboxing,
widening and upcasting)

On Fri, Nov 3, 2017 at 2:17 PM, Gavin Bierman <gavin.bierman at>

> Primitive type-test patterns
> Given that patterns include constant expressions, and type tests possibly
> including generic types; it seems reasonable to consider the possibility of
> allowing primitive type tests in pattern matching. (This answers a
> sometimes-requested feature: can instanceof support primitive types?)
> However, it is not wholly obvious what this test might mean. One
> possibility is that a “type-restating” equivalent for primitive type-test
> patterns is assignment conversion; e.g. if I have
> case int x:
> then a target whose static type is byte, short, char, or int – or their
> boxes – will be statically deemed to match.
> A target whose dynamic type can be assigned to the primitive type through
> a combination of unboxing and widening (again, assignment conversion)
> matches a primitive type test. So if we have:
> switch (o) {
>     case int i: ...
> we have to do instanceof tests against {Integer,Short,Character,Boolean}
> to determine a match.
> A primitive type test pattern dominates other primitive type patterns
> according to assingment compatibility; int dominates byte/short/char, long
> dominates int/byte/short/char, and double dominates float.
> A primitive type test pattern is inapplicable (dead) if cast conversion
> from the static type of the target fails:
> Map m;
> switch (m) {
>     case int x:  // compile error
> }
> The dominance interaction between primitive type-tests and reference
> type-tests for the wrapper types (and their supertypes) seems messy.
> Consider the following combinations:
> case int n:
> case Integer n:  // dead
> case Integer n:
> case int n:      // not dead -- still matches Short, Byte
> case Byte b:
> case byte b:     // dead
> case Number n:
> case int n:      // dead
> Is there some unifying theory that makes sense here? One possibility is to
> take a more denotational view: a type is a set of values, so type
> restatement is really about semantic set inclusion, and dynamic testing is
> about set membership. Is this adding too much complexity? Do developers
> really care about this feature?


Best Regards,
Ali Ebrahimi

More information about the amber-spec-observers mailing list