| ... | @@ -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); |
| 1311 | | 1311 | |
| 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 |
| 1317 | | 1321 | |
| 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 | } |
| 1323 | | 1334 | |
| ... | @@ -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 | } |
| 1330 | | 1341 | |
| | 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 | } |
| 1333 | | 1351 | |