You are simply declaring the array instance incorrectly. Instead of
type bit2_t is array (0 to 1) of bit;
type record0 is record
bit2 : array (0 to 1) of bit;
end record;
You need to use
type bit2_t is array (integer range <>) of bit;
type record0 is record
bit2 : bit2_t(0 to 1);
end record;
If you wanted an array of 2-bit arrays of bits, you would use
type bit2_t is array (0 to 1) of bit;
type bit2_array_t is array (integer range <>) of bit2_t;
type record0 is record
bit2 : bit2_array_t(0 to 7); -- '7' or whatever your range needs to be
end record;
You could make this slightly more generic by changing the 7 to a constant, something like bit2 : bit2_array_t(0 to BIT2_ARRAY_LENGTH-1);.
If you want to have a record type that is in some way paramatized, as far as I know you can only achieve this using package generics, as explained in this answer. Your code would use the package as described, and this package would declare your record type with array sizes based on a generic parameter. By instantiating the package with a different value for the generic in each case, your record could have different element sizes for these different cases.
I would note that I do not believe package generics are widely supported by synthesis tools.