Note that this is roughly the same reason that Java has a similar restriction imposed on its generics.
-Kenton On Thu, Apr 30, 2020 at 5:18 PM Kenton Varda <[email protected]> wrote: > Hi Samuel, > > Basically, because all pointers are the same size regardless of their > type, so varying the type of a pointer does not change the overall layout > of the containing struct. > > If the field can actually change sizes for different generic types, then > it could affect the size and position of other fields around it. For > example, imagine this: > > struct Foo(T) { > a @0 :Int16; > b @1 :Int32; > c @2 :T; > d @3 :Int64; > } > > If we replace `T` with the type `Int16`, then the struct will be laid out > like this: > > 0...16 a > 16...32 c > 32...64 b > 64...128 d > > But if we replace `T` with type `Int32`, then the struct looks like this: > > 0...16 a > 16...32 (empty padding) > 32...64 b > 64...96 c > 96...128 (empty padding) > 128...192 d > > Notice that the offset to field `d` differs between these. Also notice > that deciding the offset of d depends on the specific details of all the > fields that come before it. > > Because of this complexity, if we wanted Cap'n Proto generics to support > varying primitive types, we'd essentially be forced to output a whole copy > of the class for each combination of type parameters, because potentially > all the offsets could differ for each permutation. > > *Or* we would need to say that generic types are laid out differently from > the equivalent substituted type. > > Either of these options seemed unreasonably bad in practice. So the only > other option was to support varying pointer types only. > > Note that this rule doesn't apply to List(T) because List(T) is a built-in > type, not a generic. > > -Kenton > > On Thu, Apr 30, 2020 at 5:04 PM Samuel Ainsworth <[email protected]> > wrote: > >> Following the schema introduction (https://capnproto.org/language.html), >> I have something like the following: >> >> struct Map(Key, Value) { >> entries @0 :List(Entry); >> struct Entry { >> key @0 :Key; >> value @1 :Value; >> } >> } >> >> >> struct Directory { >> contents @0 :Map(UInt64, UInt64); >> } >> >> >> But capnproto isn't too happy about this: >> >> src/newworld/filetree.capnp:51:23-29: error: Sorry, only pointer types >> can be used as generic parameters. >> >> I understand what this is saying, but I'm a bit puzzled as to why this >> constraint exists... Why are only pointer types allowed as the >> instantiations of generic parameters? >> >> Thanks, >> Samuel >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Cap'n Proto" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com >> <https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/capnproto/CAJouXQmd1vK9wtG1TpykEeBsjUwAqzB09GZOkXJyu09tcQe5mg%40mail.gmail.com.
