commit dd50ca7740408e3c6e41c0ca48b59b9f7f5911f2
parent 1751c393045cd0ee613ab02077e0687d7ddb27d3
Author: Bor Grošelj Simić <bgs@turminal.net>
Date: Sat, 18 Feb 2023 16:20:21 +0100
remove support for self-referential locals
Closes: https://todo.sr.ht/~sircmpwn/hare/786
Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>
Diffstat:
2 files changed, 20 insertions(+), 43 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -1170,40 +1170,13 @@ check_expr_binding(struct context *ctx,
goto done;
}
- struct identifier ident = {
- .name = abinding->name,
- };
struct expression *initializer =
xcalloc(1, sizeof(struct expression));
-
- struct identifier gen = {0};
- if (abinding->is_static) {
- // Generate a static declaration identifier
- gen.name = gen_name(&ctx->id, "static.%d");
- }
-
- bool context = abinding->type
- && abinding->type->storage == STORAGE_ARRAY
- && abinding->type->array.contextual;
- const struct scope_object *shadowed =
- scope_lookup(ctx->scope, &ident);
- if (type && !context && shadowed == NULL) {
- // If the type is defined in advance, and a variable
- // isn't being shadowed, we can insert the object into
- // the scope early, which is required for
- // self-referencing objects.
- if (!abinding->is_static) {
- binding->object = scope_insert(ctx->scope,
- O_BIND, &ident, &ident, type, NULL);
- } else {
- binding->object = scope_insert(ctx->scope,
- O_DECL, &gen, &ident, type, NULL);
- }
- }
-
check_expression(ctx, abinding->initializer, initializer, type);
- if (context) {
+ if (abinding->type
+ && abinding->type->storage == STORAGE_ARRAY
+ && abinding->type->array.contextual) {
if (initializer->result->storage != STORAGE_ARRAY) {
error(ctx, aexpr->loc, expr,
"Cannot infer array length from non-array type");
@@ -1218,19 +1191,23 @@ check_expr_binding(struct context *ctx,
type = initializer->result;
}
- if (context || !type || shadowed != NULL) {
- if (!type) {
- type = type_store_lookup_with_flags(ctx->store,
- initializer->result, abinding->flags);
- }
+ if (!type) {
+ type = type_store_lookup_with_flags(ctx->store,
+ initializer->result, abinding->flags);
+ }
- if (!abinding->is_static) {
- binding->object = scope_insert(ctx->scope,
- O_BIND, &ident, &ident, type, NULL);
- } else {
- binding->object = scope_insert(ctx->scope,
- O_DECL, &gen, &ident, type, NULL);
- }
+ struct identifier ident = {
+ .name = abinding->name,
+ };
+ if (abinding->is_static) {
+ // Generate a static declaration identifier
+ struct identifier gen = {0};
+ gen.name = gen_name(&ctx->id, "static.%d");
+ binding->object = scope_insert(ctx->scope,
+ O_DECL, &gen, &ident, type, NULL);
+ } else {
+ binding->object = scope_insert(ctx->scope,
+ O_BIND, &ident, &ident, type, NULL);
}
if (type->storage == STORAGE_NULL) {
diff --git a/tests/07-aliases.ha b/tests/07-aliases.ha
@@ -98,7 +98,7 @@ type recur = struct {
fn recursive() void = {
let x: recur = struct {
- self: *recur = &x,
+ self: *recur = null: *recur,
};
x.self = &x;
assert(x.self == x.self.self);