diff options
Diffstat (limited to 'src/check_type.cpp')
| -rw-r--r-- | src/check_type.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index 2452cc6d0..b1d0045e9 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -679,6 +679,21 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast * gb_unused(where_clause_ok); } check_struct_fields(ctx, node, &struct_type->Struct.fields, &struct_type->Struct.tags, st->fields, min_field_count, struct_type, context); + + if (st->is_simple) { + bool success = true; + for (Entity *f : struct_type->Struct.fields) { + if (!is_type_nearly_simple_compare(f->type)) { + gbString s = type_to_string(f->type); + error(f->token, "'struct #simple' requires all fields to be at least 'nearly simple compare', got %s", s); + gb_string_free(s); + } + } + if (success) { + struct_type->Struct.is_simple = true; + } + } + wait_signal_set(&struct_type->Struct.fields_wait_signal); } @@ -3753,6 +3768,20 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T set_base_type(named_type, *type); return true; case_end; + + default: { + Operand o = {}; + check_expr_base(ctx, &o, e, nullptr); + + if (o.mode == Addressing_Constant && + o.value.kind == ExactValue_Typeid) { + Type *t = o.value.value_typeid; + if (t != nullptr && t != t_invalid) { + *type = t; + return true; + } + } + } } *type = t_invalid; |