There's another, probably stronger, reason why primitive patterns
supporting widening, narrowing, boxing, unboxing, etc, are basically a
forced move, besides alignment with `let` statements, discussed earlier:
There is another constraint on primitive type patterns: the let/bind
statement coming down the road. Because a type pattern looks (not
accidentally) like a local variable declaration, a let/bind we will
want to align the semantics of "local variable declaration with
initializer" and "let/bind with total type pattern". Concretely:
let String s = "foo";
is a pattern match against the (total) pattern `String s`, which
introduces `s` into the remainder of the block. Since let/bind is a
generalization of local variable declaration with initialization,
let/bind should align with locals where the two can express the same
thing. This means that the set of conversions allowed in assignment
context (JLS 5.2) should also be supported by type patterns.
The other reason is the duality with constructors (and eventually,
methods). if we have a record:
record R(int x, Long l) { }
we can construct an R with
new R(int, Long) // no adaptation
new R(Integer, Long) // unbox x
new R(short, Long) // widen x
new R(int, long) // box y
Deconstruction patterns are the dual of constructors; we should be able
to deconstruct an R with:
case R(int x, Long l) // no adaptation
case R(Integer x, Long l) // box x
case R(short s, Long l) // range check
case R(int x, long l) // unbox y, null check
So the set of adaptations in method invocation context should align with
those in nested patterns, too.