<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <br>
    <br>
    <div class="moz-cite-prefix">On 6/14/2022 2:54 PM, Dan Heidinga
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
      <blockquote type="cite" style="color: #007cff;">
        <pre class="moz-quote-pre" wrap="">But (and there's a whole conversation to be had here) it does mean that
there is separate access control on LFoo vs QFoo,
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">Pulling on this thread a little, is it the class that has different
access control or something else?</pre>
    </blockquote>
    <br>
    We've meandered a bit over the years on the distinction between the
    class Foo, the types Foo.ref and Foo.val, and their respective
    mirrors.  It's probably time for a check-in on where we are there. 
    <br>
    <br>
    Today, Integer is a class, with a full-power mirror Integer.class;
    int is a type, with a limited mirror int.class, whose job is mostly
    limited to reflecting over field and method descriptors.  <br>
    <br>
    With Valhalla, Point is a class, with types Point.ref and Point.val;
    Point.class is a full-power mirror for Point.ref, and
    Point.val.class is a limited mirror that is analogous to the int
    mirror.  If you ask a Point for its getClass(), it always returns
    Point.class.  It would not bother me if the Point.val.class mirror
    is fully limited, and the only way to do lookups (e.g., getMethods)
    is to switch over to the class mirror (for which we'd probably have
    a `Class::getPrimaryClass` method.)  <br>
    <br>
    Having the two encode separate accessibilities sounds a little
    messy, but the various Lookup::checkAccess methods key off of a
    Class, so that seems a reasonable place to hang this information.  I
    would assume such checks would check both the primary class and then
    the secondary class, or we'd arrange that the primary mirror always
    was at least as accessible as the secondary mirror.  (Protected
    isn't a useful option, and public/package/private are suitably
    ordered.)  <br>
    <br>
    At the language level, there is a question about how to present the
    val class.  One obvious (but possibly bad) idea is to pretend it is
    a special kind of nested class (which is supported by the Point.val
    naming convention):<br>
    <br>
        value class Rational { <br>
            private class val { }<br>
        }<br>
    <br>
    This is a little cheesy, but may fit mostly cleanly into user's
    mental models.   In this case, the accessibility is going on
    something that looks like a class declaration at the source level,
    and which has a class mirror at the VM level, but it really a
    "shadow class", just like the class described by int.class (or
    String[].class.)  This might be OK.  <br>
    <br>
    At one point I considered whether we could hang this on the
    accessibility of the no-arg constructor, but I quickly soured on
    this idea.  But that has an accessibility too.  <br>
    <br>
    Or we could invent a new kind of member, to describe the val
    projection, and hang accessibility on that.  <br>
    <br>
    <blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
      <pre class="moz-quote-pre" wrap="">To create an identity object, we do access control on the both class
(public/package) and the constructor (public/package/private (aka
nest)).
To create a value object, we do nest mate access control (aka private)
on the bytecodes that create values (aconst_init / withfield).  This
proposal extends the nest mates access check to the default values of
Qs.</pre>
    </blockquote>
    <br>
    It's not just nestmate access control; it would be reasonable to
    declare the val as package-access, and trust your package mates
    too.   <br>
    <br>
    <blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
      <pre class="moz-quote-pre" wrap="">In both cases, we're looking at the access control of two things - the
class and the "creator of instances".  Are we applying different
access control to LFoo vs QFoo, or to construction mechanisms?</pre>
    </blockquote>
    <br>
    The thing we're trying to protect is creation of uninitialized
    heap-based instances.  But it felt a little weird to draw such a
    complex line; seemed simpler (and not giving up much) to
    access-control the type name.  But we can explore this some more. 
    Maybe we are access-controlling the `defaultvalue` bytecode, since
    its effectively public if someone can create a flat array.  <br>
    <br>
    <br>
  </body>
</html>