| ... | ... | @@ -276,6 +276,11 @@ static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf |
| 276 | 276 | bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime); |
| 277 | 277 | static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| 278 | 278 | IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime); |
| 279 | static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, |
| 280 | AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, |
| 281 | IrInstGen *result_loc); |
| 282 | static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, |
| 283 | IrInstGen *struct_operand, TypeStructField *field); |
| 279 | 284 | |
| 280 | 285 | static void destroy_instruction_src(IrInstSrc *inst) { |
| 281 | 286 | switch (inst->id) { |
| ... | ... | @@ -14445,10 +14450,71 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 14445 | 14450 | } |
| 14446 | 14451 | |
| 14447 | 14452 | static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, |
| 14448 | | IrInstGen *value, ZigType *wanted_type) |
| 14453 | IrInstGen *value, ZigType *union_type) |
| 14449 | 14454 | { |
| 14450 | | ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); |
| 14451 | | return ira->codegen->invalid_inst_gen; |
| 14455 | Error err; |
| 14456 | ZigType *struct_type = value->value->type; |
| 14457 | |
| 14458 | assert(struct_type->id == ZigTypeIdStruct); |
| 14459 | assert(union_type->id == ZigTypeIdUnion); |
| 14460 | assert(struct_type->data.structure.src_field_count == 1); |
| 14461 | |
| 14462 | TypeStructField *only_field = struct_type->data.structure.fields[0]; |
| 14463 | |
| 14464 | if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) |
| 14465 | return ira->codegen->invalid_inst_gen; |
| 14466 | |
| 14467 | TypeUnionField *union_field = find_union_type_field(union_type, only_field->name); |
| 14468 | if (union_field == nullptr) { |
| 14469 | ir_add_error_node(ira, only_field->decl_node, |
| 14470 | buf_sprintf("no member named '%s' in union '%s'", |
| 14471 | buf_ptr(only_field->name), buf_ptr(&union_type->name))); |
| 14472 | return ira->codegen->invalid_inst_gen; |
| 14473 | } |
| 14474 | |
| 14475 | ZigType *payload_type = resolve_union_field_type(ira->codegen, union_field); |
| 14476 | if (payload_type == nullptr) |
| 14477 | return ira->codegen->invalid_inst_gen; |
| 14478 | |
| 14479 | IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, value, only_field); |
| 14480 | if (type_is_invalid(field_value->value->type)) |
| 14481 | return ira->codegen->invalid_inst_gen; |
| 14482 | |
| 14483 | IrInstGen *casted_value = ir_implicit_cast(ira, field_value, payload_type); |
| 14484 | if (type_is_invalid(casted_value->value->type)) |
| 14485 | return ira->codegen->invalid_inst_gen; |
| 14486 | |
| 14487 | if (instr_is_comptime(casted_value)) { |
| 14488 | ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); |
| 14489 | if (val == nullptr) |
| 14490 | return ira->codegen->invalid_inst_gen; |
| 14491 | |
| 14492 | IrInstGen *result = ir_const(ira, source_instr, union_type); |
| 14493 | bigint_init_bigint(&result->value->data.x_union.tag, &union_field->enum_field->value); |
| 14494 | result->value->data.x_union.payload = val; |
| 14495 | |
| 14496 | val->parent.id = ConstParentIdUnion; |
| 14497 | val->parent.data.p_union.union_val = result->value; |
| 14498 | |
| 14499 | return result; |
| 14500 | } |
| 14501 | |
| 14502 | IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), |
| 14503 | union_type, nullptr, true, true); |
| 14504 | if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { |
| 14505 | return ira->codegen->invalid_inst_gen; |
| 14506 | } |
| 14507 | |
| 14508 | IrInstGen *payload_ptr = ir_analyze_container_field_ptr(ira, only_field->name, source_instr, |
| 14509 | result_loc_inst, source_instr, union_type, true); |
| 14510 | if (type_is_invalid(payload_ptr->value->type)) |
| 14511 | return ira->codegen->invalid_inst_gen; |
| 14512 | |
| 14513 | IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, payload_ptr, casted_value, false); |
| 14514 | if (type_is_invalid(store_ptr_inst->value->type)) |
| 14515 | return ira->codegen->invalid_inst_gen; |
| 14516 | |
| 14517 | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 14452 | 14518 | } |
| 14453 | 14519 | |
| 14454 | 14520 | // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, |
| ... | ... | @@ -23050,7 +23116,7 @@ static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instructi |
| 23050 | 23116 | Error err; |
| 23051 | 23117 | assert(union_type->id == ZigTypeIdUnion); |
| 23052 | 23118 | |
| 23053 | | if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) |
| 23119 | if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) |
| 23054 | 23120 | return ira->codegen->invalid_inst_gen; |
| 23055 | 23121 | |
| 23056 | 23122 | TypeUnionField *type_field = find_union_type_field(union_type, field_name); |