diff options
| author | emekoi <emekankurumeh@outlook.com> | 2019-07-01 00:27:55 -0500 |
|---|---|---|
| committer | emekoi <emekankurumeh@outlook.com> | 2019-07-01 00:27:55 -0500 |
| commit | 2d85ff94653457ea12cd9ab0984ab3b13c9b41e5 (patch) | |
| tree | 2ef361af1cbc6679cad8c7d82114f44dcf6d7f95 /src | |
| parent | 0dd2e93e4cb28205823e840d5fdb0fccce9cc2e7 (diff) | |
| download | zig-2d85ff94653457ea12cd9ab0984ab3b13c9b41e5.tar.gz zig-2d85ff94653457ea12cd9ab0984ab3b13c9b41e5.zip | |
added invalid switch prong error
added error for switch prong with different payloads and support for capturing payload on switch prongs with payloads of the same type
Diffstat (limited to 'src')
| -rw-r--r-- | src/ir.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index abae52fcb5..d4cb5f90de 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19128,10 +19128,6 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru assert(enum_type != nullptr); assert(enum_type->id == ZigTypeIdEnum); - if (instruction->prongs_len != 1) { - return target_value_ptr; - } - IrInstruction *prong_value = instruction->prongs_ptr[0]->child; if (type_is_invalid(prong_value->value.type)) return ira->codegen->invalid_instruction; @@ -19146,6 +19142,40 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); + if (instruction->prongs_len != 1) { + ErrorMsg *invalid_payload = nullptr; + Buf *invalid_payload_list = nullptr; + + for (size_t i = 1; i < instruction->prongs_len; i++) { + IrInstruction *casted_prong_value = ir_implicit_cast(ira, instruction->prongs_ptr[i]->child, enum_type); + if (type_is_invalid(casted_prong_value->value.type)) + return ira->codegen->invalid_instruction; + + ConstExprValue *next_prong = ir_resolve_const(ira, casted_prong_value, UndefBad); + if (!next_prong) + return ira->codegen->invalid_instruction; + + ZigType *payload = find_union_field_by_tag(target_type, &next_prong->data.x_enum_tag)->type_entry; + + if (field->type_entry != payload) { + if (!invalid_payload) { + invalid_payload = ir_add_error(ira, &instruction->base, + buf_sprintf("switch prong contains cases with differing payloads")); + invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name)); + } + + if (i == instruction->prongs_len - 1) + buf_append_buf(invalid_payload_list, buf_sprintf(" and %s", buf_ptr(&payload->name))); + else + buf_append_buf(invalid_payload_list, buf_sprintf(", %s", buf_ptr(&payload->name))); + } + } + + if (invalid_payload) + add_error_note(ira->codegen, invalid_payload, + ((IrInstruction*)instruction)->source_node, invalid_payload_list); + } + if (instr_is_comptime(target_value_ptr)) { ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); if (!target_value_ptr) |
