~sircmpwn/hare-dev

harec: type_store: allow unbounded arrays with undefined member size v1 REJECTED

Autumn!: 1
 type_store: allow unbounded arrays with undefined member size

 2 files changed, 9 insertions(+), 9 deletions(-)
#1058784 alpine.yml success
#1058785 freebsd.yml success
#1058786 netbsd.yml success
One thing that I find useful about *[*]opaque is the ability to get an
opaque slice from it via regular unbounded array slicing:

fn to_slice(data: *[*]opaque, ndata: size) = {
	return data[..ndata];
};

Equivalent code without this patch involves quite a bit of casting gymnastics.
Additionally, the distinction between an opaque unbounded array and an opaque
pointer carries semantic information that may be very useful to the programmer.


so, my main reasons for this were:

marking up C-style array pointers with more useful information, as bgs 
mentioned
and then secondly it just seems unnecessary to forbid it. this patch 
just makes it so that the restriction of "you can't instantiate a type 
of undefined size" is only applied where necessary. in fact honestly 
e.g. *[4]opaque could be allowed too, since it's not doing any harm as a 
pointer, and that would remove the special case for just bounded array 
pointers. i hadn't really considered that part when i sent this patch.
the nice thing about pointers is that they're just an address to the 
start of an item, so you don't have to care about the size of the item, 
and the type checking rules for pointers can ignore undefined size -- 
this is the premise of *opaque. i think it makes sense to generalize 
this rule to pointers to items of undefined size, rather than 
special-casing opaque.
~Autumn
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/hare-dev/patches/44805/mbox | git am -3
Learn more about email & git

[PATCH harec] type_store: allow unbounded arrays with undefined member size Export this patch

Signed-off-by: Autumn! <autumnull@posteo.net>
---
 src/type_store.c   | 12 ++++++------
 tests/01-arrays.ha |  6 +++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/type_store.c b/src/type_store.c
index bbc723c..fa97802 100644
--- a/src/type_store.c
+++ b/src/type_store.c
@@ -762,17 +762,17 @@ type_init_from_atype(struct type_store *store,
			*type = builtin_type_error;
			return (struct dimensions){0};
		}
		if (memb.size == SIZE_UNDEFINED) {
			error(store->check_context, atype->loc, NULL,
				"Type of undefined size is not a valid array member");
			*type = builtin_type_error;
			return (struct dimensions){0};
		}

		type->align = memb.align;
		if (type->array.length == SIZE_UNDEFINED) {
			type->size = SIZE_UNDEFINED;
		} else {
			if (memb.size == SIZE_UNDEFINED) {
				error(store->check_context, atype->loc, NULL,
					"Type of undefined size is not a valid array member");
				*type = builtin_type_error;
				return (struct dimensions){0};
			}
			type->size = memb.size * type->array.length;
		}
		break;
diff --git a/tests/01-arrays.ha b/tests/01-arrays.ha
index fa8769a..937b6c3 100644
--- a/tests/01-arrays.ha
+++ b/tests/01-arrays.ha
@@ -167,10 +167,10 @@ fn eval_access() void = {
};

fn reject() void = {
	// unbounded arrays of values of undefined size
	assert(compile("fn f() void = { let x = null: *[*][*]int; };")
	// indexing arrays of values of undefined size
	assert(compile("fn f() void = { let x = null: *[*][*]int; x[0]};")
		as exited == EXIT_FAILURE);
	assert(compile("fn f() void = { let x = null: *[*]fn ()int; };")
	assert(compile("fn f() void = { let x = null: *[*]fn ()int; x[0]};")
		as exited == EXIT_FAILURE);

	// assignment to array of undefined size
-- 
2.42.0
tentative -1, i think hare-raylib should just use *opaque everywhere.
you don't really get much benefit from using *[*]opaque, and it's not
really possible to decide which to use programmatically
harec/patches: SUCCESS in 1m15s

[type_store: allow unbounded arrays with undefined member size][0] from [Autumn!][1]

[0]: https://lists.sr.ht/~sircmpwn/hare-dev/patches/44805
[1]: mailto:autumnull@posteo.net

✓ #1058786 SUCCESS harec/patches/netbsd.yml  https://builds.sr.ht/~sircmpwn/job/1058786
✓ #1058784 SUCCESS harec/patches/alpine.yml  https://builds.sr.ht/~sircmpwn/job/1058784
✓ #1058785 SUCCESS harec/patches/freebsd.yml https://builds.sr.ht/~sircmpwn/job/1058785
Hm, I'm not sure this is a good idea.

The main use-case for slice members with undefined size is []opaque,
since []opaque has the unique property that all slice types are
assignable to it. *[*]opaque doesn't have this property, and thus
there's not much reason to use it. You can't index from it, so you'd
need to cast it into a pointer to some other array type anyway,
something which is already possible with *opaque.

I guess another way of putting it is this: it doesn't make sense to have
an array of an opaque type, since by definition the opaque type is,
well, opaque. This is true whether or not the array is bounded: an
unbounded array is still an array, just without a known length/size, but
it still doesn't make sense to store opaque data within it. [*]opaque
is, itself, a type whose representation is undefined since the data is
opaque. But that makes [*]opaque indistinguishable from opaque itself.
Case in point: bounded arrays whose member has undefined size don't make
sense, and aren't allowed by this patch. But I argue that the same
reasoning for disallowing bounded arrays here also applies to unbounded
arrays.

Opaque slices make more sense, since internally a slice just stores a
pointer, and that pointer is to opaque data. But the opaque data isn't
stored within the representation of the slice itself.

This is to say that [*]opaque doesn't fill any particular niche that
isn't already filled by opaque itself, so I think it's simpler to just
disallow it entirely.