authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-24 13:47:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-24 13:47:07-07:00
log08a7ce7dd5f348b37bf98c5040ad58720a7818b5
treedeb58ea9bc24f131a81e18784b5904947cac2df6
parent8915883cf627c12a7e6da9bb813d456407ebb091

add error for missing or duplicate field in struct value expr


2 files changed, 50 insertions(+), 2 deletions(-)

src/analyze.cpp+20-2
...@@ -1309,7 +1309,11 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1309,7 +1309,11 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1309 node->codegen_node->data.struct_val_expr_node.source_node = node;1309 node->codegen_node->data.struct_val_expr_node.source_node = node;
1310 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);1310 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
13111311
1312 for (int i = 0; i < struct_val_expr->fields.length; i += 1) {1312 int expr_field_count = struct_val_expr->fields.length;
1313 int actual_field_count = type_entry->data.structure.field_count;
1314
1315 int *field_use_counts = allocate<int>(actual_field_count);
1316 for (int i = 0; i < expr_field_count; i += 1) {
1313 AstNode *val_field_node = struct_val_expr->fields.at(i);1317 AstNode *val_field_node = struct_val_expr->fields.at(i);
1314 int field_index;1318 int field_index;
1315 TypeStructField *type_field = find_struct_type_field(type_entry,1319 TypeStructField *type_field = find_struct_type_field(type_entry,
...@@ -1317,7 +1321,14 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1317,7 +1321,14 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
13171321
1318 if (!type_field) {1322 if (!type_field) {
1319 add_node_error(g, val_field_node,1323 add_node_error(g, val_field_node,
1320 buf_sprintf("type '%s' is not a struct", buf_ptr(&type_entry->name)));1324 buf_sprintf("no member named '%s' in '%s'",
1325 buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&type_entry->name)));
1326 continue;
1327 }
1328
1329 field_use_counts[field_index] += 1;
1330 if (field_use_counts[field_index] > 1) {
1331 add_node_error(g, val_field_node, buf_sprintf("duplicate field"));
1321 continue;1332 continue;
1322 }1333 }
13231334
...@@ -1328,6 +1339,13 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1328,6 +1339,13 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1328 val_field_node->data.struct_val_field.expr);1339 val_field_node->data.struct_val_field.expr);
1329 }1340 }
13301341
1342 for (int i = 0; i < actual_field_count; i += 1) {
1343 if (field_use_counts[i] == 0) {
1344 add_node_error(g, node,
1345 buf_sprintf("missing field: '%s'", buf_ptr(type_entry->data.structure.fields[i].name)));
1346 }
1347 }
1348
1331 return type_entry;1349 return type_entry;
1332}1350}
13331351
test/run_tests.cpp+30
...@@ -877,6 +877,36 @@ struct A { y : i32, }...@@ -877,6 +877,36 @@ struct A { y : i32, }
877struct A { x : i32, }877struct A { x : i32, }
878export fn f(a : A) {}878export fn f(a : A) {}
879 )SOURCE", 1, ".tmp_source.zig:3:13: error: byvalue struct parameters not yet supported on exported functions");879 )SOURCE", 1, ".tmp_source.zig:3:13: error: byvalue struct parameters not yet supported on exported functions");
880
881 add_compile_fail_case("duplicate field in struct value expression", R"SOURCE(
882struct A {
883 x : i32,
884 y : i32,
885 z : i32,
886}
887fn f() {
888 const a = A {
889 .z = 1,
890 .y = 2,
891 .x = 3,
892 .z = 4,
893 };
894}
895 )SOURCE", 1, ".tmp_source.zig:12:9: error: duplicate field");
896
897 add_compile_fail_case("missing field in struct value expression", R"SOURCE(
898struct A {
899 x : i32,
900 y : i32,
901 z : i32,
902}
903fn f() {
904 const a = A {
905 .z = 4,
906 .y = 2,
907 };
908}
909 )SOURCE", 1, ".tmp_source.zig:8:15: error: missing field: 'x'");
880}910}
881911
882static void print_compiler_invocation(TestCase *test_case) {912static void print_compiler_invocation(TestCase *test_case) {