aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-11-05 13:51:12 +0000
committerGitHub <noreply@github.com>2025-11-05 13:51:12 +0000
commit4f0908584b2047d7722d535c596179d3620e9310 (patch)
treece90ab9ff0cd888fa6092ecb852d6934b0bdc877 /src/check_expr.cpp
parentea5db0e04864f7e453a5b5faa305df22543c4b75 (diff)
parentc937d38db2b31b885256b9aac0d606032f6c5343 (diff)
Merge pull request #5890 from odin-lang/bill/all_or_none
`struct #all_or_none`
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 8ac277917..677735c44 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -9838,6 +9838,51 @@ gb_internal void check_compound_literal_field_values(CheckerContext *c, Slice<As
c->bit_field_bit_size = prev_bit_field_bit_size;
}
+
+ if (bt->kind == Type_Struct && bt->Struct.is_all_or_none && elems.count > 0 && bt->Struct.fields.count > 0) {
+ PtrSet<Entity *> missing_fields = {};
+ defer (ptr_set_destroy(&missing_fields));
+
+ for_array(i, bt->Struct.fields) {
+ Entity *field = bt->Struct.fields[i];
+ String name = field->token.string;
+ if (is_blank_ident(name) || name == "") {
+ continue;
+ }
+ bool found = string_set_exists(&fields_visited, name);
+ String *raw_union = string_map_get(&fields_visited_through_raw_union, name);
+ if (!found && raw_union == nullptr) {
+ ptr_set_add(&missing_fields, field);
+ }
+ }
+
+ if (missing_fields.count > 0) {
+ ERROR_BLOCK();
+
+ if (build_context.terse_errors) {
+ gbString fields_string = gb_string_make(heap_allocator(), "");
+ defer (gb_string_free(fields_string));
+ isize i = 0;
+ FOR_PTR_SET(field, missing_fields) {
+ if (i > 0) {
+ fields_string = gb_string_appendc(fields_string, ", ");
+ }
+ String name = field->token.string;
+ fields_string = gb_string_append_length(fields_string, name.text, name.len);
+ i += 1;
+ }
+
+ error(o->expr, "All or none of the fields must be assigned to a struct with '#all_or_none' applied, missing fields: %s", fields_string);
+ } else {
+ error(o->expr, "All or none of the fields must be assigned to a struct with '#all_or_none' applied, missing fields:");
+ FOR_PTR_SET(field, missing_fields) {
+ gbString s = type_to_string(field->type);
+ error_line("\t%.*s: %s\n", LIT(field->token.string), s);
+ gb_string_free(s);
+ }
+ }
+ }
+ }
}
gb_internal bool is_expr_inferred_fixed_array(Ast *type_expr) {