From 2201f365a1676f966fff5b9a79f0f56b5c1cf7ee Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 3 May 2024 14:51:02 +0100 Subject: Allow `#no_alias` on multi-pointers --- src/check_type.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index ab8c0b057..61c502a68 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2017,8 +2017,8 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para } if (p->flags&FieldFlag_no_alias) { - if (!is_type_pointer(type)) { - error(name, "'#no_alias' can only be applied pointer typed parameters"); + if (!is_type_pointer(type) && !is_type_multi_pointer(type)) { + error(name, "'#no_alias' can only be applied pointer or multi-pointer typed parameters"); p->flags &= ~FieldFlag_no_alias; // Remove the flag } } -- cgit v1.2.3 From 6ec7845249d2e77e68f2e802e3bebe5b5fc3480f Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Mon, 6 May 2024 18:27:34 -0400 Subject: Fix #3531 Individual `bit_field` size was not being added to the total size. Error message was changed to be more explicit. --- src/check_type.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 61c502a68..457375779 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1080,6 +1080,8 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, array_add(&tags, tag); add_entity_use(ctx, field, e); + + total_bit_size += bit_size_u8; } } @@ -1094,7 +1096,7 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, if (total_bit_size > maximum_bit_size) { gbString s = type_to_string(backing_type); - error(node, "The numbers required %llu exceeds the backing type's (%s) bit size %llu", + error(node, "The total bit size of a bit_field's fields (%llu) must fit into its backing type's (%s) bit size of %llu", cast(unsigned long long)total_bit_size, s, cast(unsigned long long)maximum_bit_size); -- cgit v1.2.3 From 0da6a3e214c66e2955307e2aad12d844a051f8d8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 May 2024 11:42:48 +0100 Subject: Fix #3530 --- src/check_type.cpp | 9 +++++++-- src/parser.cpp | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 457375779..6efac54d6 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -797,11 +797,11 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam enum_type->Enum.scope = ctx->scope; Type *base_type = t_int; - if (et->base_type != nullptr) { + if (unparen_expr(et->base_type) != nullptr) { base_type = check_type(ctx, et->base_type); } - if (base_type == nullptr || !is_type_integer(base_type)) { + if (base_type == nullptr || base_type == t_invalid || !is_type_integer(base_type)) { error(node, "Base type for enumeration must be an integer"); return; } @@ -3265,6 +3265,11 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T case_end; case_ast_node(pe, ParenExpr, e); + if (pe->expr == nullptr) { + error(e, "Expected an expression or type within the parentheses"); + *type = t_invalid; + return true; + } *type = check_type_expr(ctx, pe->expr, named_type); set_base_type(named_type, *type); return true; diff --git a/src/parser.cpp b/src/parser.cpp index 2bf25c768..04505cbd7 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3499,6 +3499,10 @@ gb_internal Ast *parse_type(AstFile *f) { Token token = advance_token(f); syntax_error(token, "Expected a type"); return ast_bad_expr(f, token, f->curr_token); + } else if (type->kind == Ast_ParenExpr && + unparen_expr(type) == nullptr) { + syntax_error(type, "Expected a type within the parentheses"); + return ast_bad_expr(f, type->ParenExpr.open, type->ParenExpr.close); } return type; } -- cgit v1.2.3 From 0cec2d7827a537557555bf6c92c2f090113806a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 May 2024 11:51:06 +0100 Subject: Fix #3527 --- src/check_type.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 6efac54d6..ea249c293 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1430,6 +1430,10 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special bool can_convert = check_cast_internal(ctx, &o, specialization); return can_convert; } else if (t->kind == Type_Struct) { + if (t->Struct.polymorphic_parent == nullptr && + t == s) { + return true; + } if (t->Struct.polymorphic_parent == specialization) { return true; } @@ -1479,6 +1483,10 @@ gb_internal bool check_type_specialization_to(CheckerContext *ctx, Type *special return true; } } else if (t->kind == Type_Union) { + if (t->Union.polymorphic_parent == nullptr && + t == s) { + return true; + } if (t->Union.polymorphic_parent == specialization) { return true; } -- cgit v1.2.3 From 3f7a369aa1ff90ec1c71e6b4805778d4899790a5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 7 May 2024 14:53:02 +0100 Subject: Check for specialization in `typeid/T` for parapoly records --- src/check_type.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/check_type.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index ea249c293..c119ce6b5 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -381,6 +381,7 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly Type *type = nullptr; bool is_type_param = false; bool is_type_polymorphic_type = false; + Type *specialization = nullptr; if (type_expr == nullptr && default_value == nullptr) { error(param, "Expected a type for this parameter"); continue; @@ -393,7 +394,6 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly } if (type_expr->kind == Ast_TypeidType) { is_type_param = true; - Type *specialization = nullptr; if (type_expr->TypeidType.specialization != nullptr) { Ast *s = type_expr->TypeidType.specialization; specialization = check_type(ctx, s); @@ -471,6 +471,15 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly if (is_type_polymorphic(base_type(operand.type))) { *is_polymorphic_ = true; can_check_fields = false; + } else if (specialization && + !check_type_specialization_to(ctx, specialization, operand.type, false, /*modify_type*/true)) { + if (!ctx->no_polymorphic_errors) { + gbString t = type_to_string(operand.type); + gbString s = type_to_string(specialization); + error(operand.expr, "Cannot convert type '%s' to the specialization '%s'", t, s); + gb_string_free(s); + gb_string_free(t); + } } e = alloc_entity_type_name(scope, token, operand.type); e->TypeName.is_type_alias = true; -- cgit v1.2.3 From d85c8f0b2c5989f7d14b02c9023060990d241111 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 May 2024 10:58:57 +0100 Subject: Fix #3555 --- src/check_decl.cpp | 11 +++++++++++ src/check_type.cpp | 1 + src/entity.cpp | 1 + src/types.cpp | 4 ++++ 4 files changed, 17 insertions(+) (limited to 'src/check_type.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 5b9486873..441c8000d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1619,6 +1619,17 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (e->kind != Entity_Variable) { continue; } + if (is_type_polymorphic(e->type)) { + gbString s = type_to_string(e->type); + char const *msg = "Unspecialized polymorphic types are not allowed in procedure parameters, got %s"; + if (e->Variable.type_expr) { + error(e->Variable.type_expr, msg, s); + } else { + error(e->token, msg, s); + } + gb_string_free(s); + } + if (!(e->flags & EntityFlag_Using)) { continue; } diff --git a/src/check_type.cpp b/src/check_type.cpp index c119ce6b5..3d11b5012 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2076,6 +2076,7 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para param = alloc_entity_param(scope, name->Ident.token, type, is_using, true); param->Variable.param_value = param_value; param->Variable.field_group_index = field_group_index; + param->Variable.type_expr = type_expr; } } if (p->flags&FieldFlag_no_alias) { diff --git a/src/entity.cpp b/src/entity.cpp index d76d5f441..60ca208ec 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -210,6 +210,7 @@ struct Entity { CommentGroup *comment; } Constant; struct { + Ast *type_expr; // only used for some variables within procedure bodies Ast *init_expr; // only used for some variables within procedure bodies i32 field_index; i32 field_group_index; diff --git a/src/types.cpp b/src/types.cpp index 3ec05059f..30e009086 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3267,6 +3267,10 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } } + if (is_type_polymorphic(type)) { + // NOTE(bill): A polymorphic struct has no fields, this only hits in the case of an error + return sel; + } wait_signal_until_available(&type->Struct.fields_wait_signal); isize field_count = type->Struct.fields.count; if (field_count != 0) for_array(i, type->Struct.fields) { -- cgit v1.2.3 From f54977336b27c32eab52b77d94e7b1610f4350cf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 9 May 2024 15:56:00 +0100 Subject: With `-vet-style`, give suggestion of separating where clauses with a comma rather than '&&' This improves the error messages --- src/check_expr.cpp | 14 ++++++++++++++ src/check_type.cpp | 2 +- src/parser.cpp | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/check_type.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 013638e63..98aebfe4e 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6193,6 +6193,20 @@ gb_internal bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Sco } return false; } + + if (ast_file_vet_style(ctx->file)) { + Ast *c = unparen_expr(clause); + if (c->kind == Ast_BinaryExpr && c->BinaryExpr.op.kind == Token_CmpAnd) { + ERROR_BLOCK(); + error(c, "Prefer to separate 'where' clauses with a comma rather than '&&'"); + gbString x = expr_to_string(c->BinaryExpr.left); + gbString y = expr_to_string(c->BinaryExpr.right); + error_line("\tSuggestion: '%s, %s'", x, y); + gb_string_free(y); + gb_string_free(x); + } + } + } } diff --git a/src/check_type.cpp b/src/check_type.cpp index 3d11b5012..11e332757 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1166,7 +1166,7 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, } } if (all_ones && all_booleans) { - if (build_context.vet_flags & VetFlag_Style) { + if (ast_file_vet_style(ctx->file)) { char const *msg = "This 'bit_field' is better expressed as a 'bit_set' since all of the fields are booleans, of 1-bit in size, and the backing type is an integer (-vet-style)"; error(node, msg); } else { diff --git a/src/parser.cpp b/src/parser.cpp index 04505cbd7..6e859fe32 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,7 +1,7 @@ #include "parser_pos.cpp" gb_internal u64 ast_file_vet_flags(AstFile *f) { - if (f->vet_flags_set) { + if (f != nullptr && f->vet_flags_set) { return f->vet_flags; } return build_context.vet_flags; -- cgit v1.2.3