diff --git a/code/demo.odin b/code/demo.odin index dc93ab9e9..5b1c82522 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -8,6 +8,13 @@ #import "halloc.odin"; main :: proc() { + m: map[int]int; + m[123] = 312; + fmt.println(m[123]); + delete(m, 123); + fmt.println(m[123]); + + /* /* Version 0.1.1 diff --git a/core/fmt.odin b/core/fmt.odin index 6e0856ecb..d340bbe5d 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -11,8 +11,6 @@ Buffer :: struct { length: int, } - - buffer_write :: proc(buf: ^Buffer, b: []byte) { if buf.length < buf.data.count { n := min(buf.data.count-buf.length, b.count); diff --git a/src/check_expr.c b/src/check_expr.c index a36838f97..4c1deb265 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -2576,6 +2576,27 @@ isize entity_overload_count(Scope *s, String name) { return 1; } +bool check_is_field_exported(Checker *c, Entity *field) { + if (field == NULL) { + // NOTE(bill): Just incase + return true; + } + if (field->kind != Entity_Variable) { + return true; + } + Scope *file_scope = field->scope; + if (file_scope == NULL) { + return true; + } + while (!file_scope->is_file) { + file_scope = file_scope->parent; + } + if (!is_entity_exported(field) && file_scope != c->context.file_scope) { + return false; + } + return true; +} + Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_hint) { ast_node(se, SelectorExpr, node); @@ -2701,7 +2722,13 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h if (entity == NULL && selector->kind == AstNode_Ident) { - sel = lookup_field(c->allocator, operand->type, selector->Ident.string, operand->mode == Addressing_Type); + String field_name = selector->Ident.string; + sel = lookup_field(c->allocator, operand->type, field_name, operand->mode == Addressing_Type); + + if (operand->mode != Addressing_Type && !check_is_field_exported(c, sel.entity)) { + error_node(op_expr, "`%.*s` is an unexported field", LIT(field_name)); + goto error; + } entity = sel.entity; // NOTE(bill): Add type info needed for fields like `names` @@ -4470,16 +4497,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint error_node(elem, "Unknown field `%.*s` in structure literal", LIT(name)); continue; } - if (!is_unknown) { - Entity *f = sel.entity; - Scope *file_scope = f->scope; - while (!file_scope->is_file) { - file_scope = file_scope->parent; - } - if (!is_entity_exported(f) && file_scope != c->context.file_scope) { - error_node(elem, "Cannot assign to an unexported field `%.*s` in structure literal", LIT(name)); - continue; - } + if (!is_unknown && !check_is_field_exported(c, sel.entity)) { + error_node(elem, "Cannot assign to an unexported field `%.*s` in structure literal", LIT(name)); + continue; } @@ -4524,11 +4544,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint break; } - Scope *file_scope = field->scope; - while (!file_scope->is_file) { - file_scope = file_scope->parent; - } - if (!is_entity_exported(field) && file_scope != c->context.file_scope) { + if (!check_is_field_exported(c, field)) { gbString t = type_to_string(type); error_node(o->expr, "Implicit assignment to an unexported field `%.*s` in `%s` literal", LIT(field->token.string), t);