[patterns] primitive widening

Remi Forax forax at univ-mlv.fr
Sun Oct 15 09:33:12 UTC 2017


I do not think that a Short should matches a long if the pattern matching is defined as a suite of matches, the behavior will be weird.
By example with,
  Object x = new Short();
  switch(x) {
    case long l: ...
    case short s: ...
  }
it will be surprising that the first case matches.

In my opinion, we should stick to
  matches = instanceof + cast
the instanceof part is a plain old instanceof and the cast can be an unboxing but not a widening conversion
so with x an object
  x matches long l <=> x instanceof Long + unbox Long

With your example,
  void test(Short x) {
    assert(x matches long l);  // compile error, because x instanceof Long is a compile error 
  }

regards,
Rémi

----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Dimanche 15 Octobre 2017 01:02:14
> Objet: [patterns] primitive widening

> Interesting question:  Should a "Short" box value
> match a "long" primitive?  More generally, should
> pattern matching emulate assignment conversions?
> Including primitive widening conversions?
> 
> Probably the answer is yes, under the theory that
> a pattern match digs through dynamic information to
> search for a *possible* assignment, and then (along
> that "match succeeded" path, is ready to make the
> assignment to a binding variable.
> 
>    void test(Short x) {
>        long y = x; //OK
>        longConsumer(x); //OK
>        assert(x matches long);  //OK??
>    }
>    void longConsumer(long z) { }
> 
> Does the prototype work that way?  No, there is just an
> open-coded instanceof test of the wrapper type
> (makeTypeTest … boxedTypeOrType).
> 
> This is tricky to implement dynamically, but MH.invoke
> gets these details correct already, since it makes a
> dynamic emulation of (many of) Java's static rules for
> method argument conversion.
> 
> ("Many of" means that the dynamic emulation is aware
> only of reified types, as if only raw types were present.
> Happily, the Core Reflection API also does the same
> emulation, although with different exceptions thrown.)
> 
> These are the relevant routines from the MH runtime:
>  sun.invoke.util.Wrapper::isConvertibleFrom
>  sun.invoke.util.Wrapper::convert
> 
> One good thing about this messy stuff:  The widening
> primitive conversions (and narrowing ones, in the case
> of a cast) only come into play when the target type is
> really a primitive, not just a reference wrapping one.
> 
> So we don't have to match a Short to a Long, just
> a Byte, Short, Character, Integer, Float, and Long to
> a primitive long (if the source type is a reference
> type that can contain any or all of the above).
> 
> A factored runtime for pattern matching will be able
> to use the MH routines, if we decide that's the correct
> behavior.  By "factored runtime" I hope for, of course,
> something with a metafactory for each switch and
> pattern.
> 
> — John


More information about the amber-dev mailing list