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.

Reply via email to