Some quick answers…
> Where in the template class file are holes allowed? "almost anywhere in the
> constant pool”
The constant pool is divided into “segments”, and the holes are a property of
the segment. In the original doc, the constraint was that the holes were the
first N constants in the segment. An alternate way to do this is how M3 did
it, where there was a “table of contents” early in the classfile, which
enumerated the segments, and identified the holes that go with each.
Whether a hole is defined by a constant pool entry or an entry in a segment
table is largely a “syntax” choice.
Since each segment is associated with a number of holes, and classes/members
are associated with segments, it stands to reason that we need to type-check
the relationship between the number and kinds of holes in a segment, and an
attempt to specialize the class or method defined in that segment. If I have a
segment with two holes of kind “TYPE”, its probably an error to instantiate it
with three type parameters, or parameters that are not of kind TYPE. (Though
there may be some need to support mismatches for reasons of compatible
evolution.)
Where we would previously reference a class (Constant_Class, or LFoo;
descriptor), we instead need a way to reference a species. The M3 document
showed one way to do this; a ParamType constant, which captures the template
name and the parameters. Then, a species is allowed basically anywhere a class
was previously — in descriptor strings, in Constant_Class, as the operand of a
new/checkcast/instanceof, as the owner of a Field or Method ref, etc.
>
> What about the user mode assumption that: if Foo extends Bar, Foo<Point> is a
> subclass of Bar<Point>
This is handled by the translation scheme. If Foo<T> extends Bar<T>, then the
superclass of Foo<T> will be Bar<T>. In M3, we’d write this as ParamType[Bar,
TypeVar[0//Object]], which means that when Foo is specialized with a real type
T, the super type is Bar<T>, and when Foo is specialized with erased, the suer
type is erased Bar.
> Is it the case that a specialization could always have two segments
As the proposal is written, a specialized class would have at least two
segments — the “true constants” segment, and the “specialized class” segment.
The intent, though, is that nested generic members (methods, and maybe even
inner classes) would have their own segment too. And segments inherit holes
from their parents.
Note too that compilers often desugar one member into more than one; if a
generic method has a lambda in it, that lambda will get its own method, but it
should go into the segment for the generic method, not the class. Then the
right things happen automatically.
Bringing inner classes into a single template may sound like a radical move,
but its a powerful one; inner classes share so much with their enclosing class,
that being able to inherit holes and constants from the class would result in
lots more sharing.
> Why extend super-interfaces to Constant_Dynamic? When would the BSM be
> invoked? Is the intent here to allow superinterfaces with holes - couldn't
> that be handled via a template type species?
John is looking ahead here to a feature we would like to have. Suppose I have
an interface like Comparable. And suppose I want to create a Box<T> type, and
I want to lift the comparability of T onto Box<T>. That is, if T is ordered,
then I can derive an order on Box<T> from the order on T. And I would like
that to be reflected as a conditional super type. I might express that in Java
code like:
class Box<T>
<when T extends Comparable<T>> implements Comparable<Box<T>> { … }
Having a bootstrap that comes up with the list of supertypes as function of
the type parameters allows such things to be represented.
> Relationship between: raw type, template class, erased species
There are two questions embedded here:
- are the above all types, and if so what is their subtyping relationships,
- what is the relationship between the _members_ of these various types
Our working story is that in the VM, there are _class_ and_species_ types.
From a template class, we derive a class type and a mechanism for deriving the
species types from their type parameters. The compiler translates uses of
wildcard and raw types as the class. The Class is a super type of all the
species of that template.
Separately, the compiler ensures (through the translation model) that the
_class_ has all the same members as the erased species. So for any member m in
the erased species, call sites / access sites for c.m will link, where c is of
the class type.
> proposal is that the template class is not instantiable
Yes but …
Old code (and maybe new) will have `new Foo` byptecodes in them; we’d like to
redirect these to instantiate the erased species.
> Request from vm runtime
> in the specialized class file, we need both the name/UTF8 string AND the
> Constant_Class to have a place to store the passed-in resolved type parameter
Yes, definitely. M3 sidestepped this as a prototyping move, but we need to
meet this head-on, and its a nasty problem.