Browse Source

Clear error message on collisions with `using` on struct fields

gingerBill 1 year ago
parent
commit
7cd2bc26f4
1 changed files with 8 additions and 5 deletions
  1. 8 5
      src/check_type.cpp

+ 8 - 5
src/check_type.cpp

@@ -29,10 +29,11 @@ gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstF
 	}
 	}
 }
 }
 
 
-gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t) {
+gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field, Type *t, isize level) {
 	if (t == nullptr) {
 	if (t == nullptr) {
 		return;
 		return;
 	}
 	}
+	Type *original_type = t;
 	t = base_type(type_deref(t));
 	t = base_type(type_deref(t));
 	gbString str = nullptr;
 	gbString str = nullptr;
 	defer (gb_string_free(str));
 	defer (gb_string_free(str));
@@ -46,16 +47,18 @@ gb_internal void populate_using_entity_scope(CheckerContext *ctx, Ast *node, Ast
 			String name = f->token.string;
 			String name = f->token.string;
 			Entity *e = scope_lookup_current(ctx->scope, name);
 			Entity *e = scope_lookup_current(ctx->scope, name);
 			if (e != nullptr && name != "_") {
 			if (e != nullptr && name != "_") {
+				gbString ot = type_to_string(original_type);
 				// TODO(bill): Better type error
 				// TODO(bill): Better type error
 				if (str != nullptr) {
 				if (str != nullptr) {
-					error(e->token, "'%.*s' is already declared in '%s'", LIT(name), str);
+					error(e->token, "'%.*s' is already declared in '%s', through 'using' from '%s'", LIT(name), str, ot);
 				} else {
 				} else {
-					error(e->token, "'%.*s' is already declared", LIT(name));
+					error(e->token, "'%.*s' is already declared, through 'using' from '%s'", LIT(name), ot);
 				}
 				}
+				gb_string_free(ot);
 			} else {
 			} else {
 				add_entity(ctx, ctx->scope, nullptr, f);
 				add_entity(ctx, ctx->scope, nullptr, f);
 				if (f->flags & EntityFlag_Using) {
 				if (f->flags & EntityFlag_Using) {
-					populate_using_entity_scope(ctx, node, field, f->type);
+					populate_using_entity_scope(ctx, node, field, f->type, level+1);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -200,7 +203,7 @@ gb_internal void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entit
 				continue;
 				continue;
 			}
 			}
 
 
-			populate_using_entity_scope(ctx, node, p, type);
+			populate_using_entity_scope(ctx, node, p, type, 1);
 		}
 		}
 
 
 		if (is_subtype && p->names.count > 0) {
 		if (is_subtype && p->names.count > 0) {