瀏覽代碼

Unexported struct fields on selectors

Ginger Bill 8 年之前
父節點
當前提交
c0d5237b75
共有 3 個文件被更改,包括 39 次插入18 次删除
  1. 7 0
      code/demo.odin
  2. 0 2
      core/fmt.odin
  3. 32 16
      src/check_expr.c

+ 7 - 0
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

+ 0 - 2
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);

+ 32 - 16
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);