| ... | ... | @@ -7468,6 +7468,17 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 7468 | 7468 | } |
| 7469 | 7469 | } |
| 7470 | 7470 | |
| 7471 | // implicit union to its enum tag type |
| 7472 | if (expected_type->id == TypeTableEntryIdEnum && actual_type->id == TypeTableEntryIdUnion && |
| 7473 | (actual_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| 7474 | actual_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) |
| 7475 | { |
| 7476 | type_ensure_zero_bits_known(ira->codegen, actual_type); |
| 7477 | if (actual_type->data.unionation.tag_type == expected_type) { |
| 7478 | return ImplicitCastMatchResultYes; |
| 7479 | } |
| 7480 | } |
| 7481 | |
| 7471 | 7482 | // implicit enum to union which has the enum as the tag type |
| 7472 | 7483 | if (expected_type->id == TypeTableEntryIdUnion && actual_type->id == TypeTableEntryIdEnum && |
| 7473 | 7484 | (expected_type->data.unionation.decl_node->data.container_decl.auto_enum || |
| ... | ... | @@ -7508,33 +7519,53 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7508 | 7519 | IrInstruction *cur_inst = instructions[i]; |
| 7509 | 7520 | TypeTableEntry *cur_type = cur_inst->value.type; |
| 7510 | 7521 | TypeTableEntry *prev_type = prev_inst->value.type; |
| 7522 | |
| 7511 | 7523 | if (type_is_invalid(cur_type)) { |
| 7512 | 7524 | return cur_type; |
| 7513 | | } else if (prev_type->id == TypeTableEntryIdUnreachable) { |
| 7525 | } |
| 7526 | |
| 7527 | if (prev_type->id == TypeTableEntryIdUnreachable) { |
| 7514 | 7528 | prev_inst = cur_inst; |
| 7515 | | } else if (cur_type->id == TypeTableEntryIdUnreachable) { |
| 7516 | 7529 | continue; |
| 7517 | | } else if (prev_type->id == TypeTableEntryIdPureError) { |
| 7530 | } |
| 7531 | |
| 7532 | if (cur_type->id == TypeTableEntryIdUnreachable) { |
| 7533 | continue; |
| 7534 | } |
| 7535 | |
| 7536 | if (prev_type->id == TypeTableEntryIdPureError) { |
| 7518 | 7537 | prev_inst = cur_inst; |
| 7519 | 7538 | continue; |
| 7520 | | } else if (prev_type->id == TypeTableEntryIdNullLit) { |
| 7539 | } |
| 7540 | |
| 7541 | if (prev_type->id == TypeTableEntryIdNullLit) { |
| 7521 | 7542 | prev_inst = cur_inst; |
| 7522 | 7543 | continue; |
| 7523 | | } else if (cur_type->id == TypeTableEntryIdPureError) { |
| 7544 | } |
| 7545 | |
| 7546 | if (cur_type->id == TypeTableEntryIdPureError) { |
| 7524 | 7547 | if (prev_type->id == TypeTableEntryIdArray) { |
| 7525 | 7548 | convert_to_const_slice = true; |
| 7526 | 7549 | } |
| 7527 | 7550 | any_are_pure_error = true; |
| 7528 | 7551 | continue; |
| 7529 | | } else if (cur_type->id == TypeTableEntryIdNullLit) { |
| 7552 | } |
| 7553 | |
| 7554 | if (cur_type->id == TypeTableEntryIdNullLit) { |
| 7530 | 7555 | any_are_null = true; |
| 7531 | 7556 | continue; |
| 7532 | | } else if (types_match_const_cast_only(prev_type, cur_type)) { |
| 7557 | } |
| 7558 | |
| 7559 | if (types_match_const_cast_only(prev_type, cur_type)) { |
| 7533 | 7560 | continue; |
| 7534 | | } else if (types_match_const_cast_only(cur_type, prev_type)) { |
| 7561 | } |
| 7562 | |
| 7563 | if (types_match_const_cast_only(cur_type, prev_type)) { |
| 7535 | 7564 | prev_inst = cur_inst; |
| 7536 | 7565 | continue; |
| 7537 | | } else if (prev_type->id == TypeTableEntryIdInt && |
| 7566 | } |
| 7567 | |
| 7568 | if (prev_type->id == TypeTableEntryIdInt && |
| 7538 | 7569 | cur_type->id == TypeTableEntryIdInt && |
| 7539 | 7570 | prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) |
| 7540 | 7571 | { |
| ... | ... | @@ -7542,36 +7573,51 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7542 | 7573 | prev_inst = cur_inst; |
| 7543 | 7574 | } |
| 7544 | 7575 | continue; |
| 7545 | | } else if (prev_type->id == TypeTableEntryIdFloat && |
| 7546 | | cur_type->id == TypeTableEntryIdFloat) |
| 7547 | | { |
| 7576 | } |
| 7577 | |
| 7578 | if (prev_type->id == TypeTableEntryIdFloat && cur_type->id == TypeTableEntryIdFloat) { |
| 7548 | 7579 | if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { |
| 7549 | 7580 | prev_inst = cur_inst; |
| 7550 | 7581 | } |
| 7551 | | } else if (prev_type->id == TypeTableEntryIdErrorUnion && |
| 7582 | continue; |
| 7583 | } |
| 7584 | |
| 7585 | if (prev_type->id == TypeTableEntryIdErrorUnion && |
| 7552 | 7586 | types_match_const_cast_only(prev_type->data.error.child_type, cur_type)) |
| 7553 | 7587 | { |
| 7554 | 7588 | continue; |
| 7555 | | } else if (cur_type->id == TypeTableEntryIdErrorUnion && |
| 7589 | } |
| 7590 | |
| 7591 | if (cur_type->id == TypeTableEntryIdErrorUnion && |
| 7556 | 7592 | types_match_const_cast_only(cur_type->data.error.child_type, prev_type)) |
| 7557 | 7593 | { |
| 7558 | 7594 | prev_inst = cur_inst; |
| 7559 | 7595 | continue; |
| 7560 | | } else if (prev_type->id == TypeTableEntryIdMaybe && |
| 7596 | } |
| 7597 | |
| 7598 | if (prev_type->id == TypeTableEntryIdMaybe && |
| 7561 | 7599 | types_match_const_cast_only(prev_type->data.maybe.child_type, cur_type)) |
| 7562 | 7600 | { |
| 7563 | 7601 | continue; |
| 7564 | | } else if (cur_type->id == TypeTableEntryIdMaybe && |
| 7602 | } |
| 7603 | |
| 7604 | if (cur_type->id == TypeTableEntryIdMaybe && |
| 7565 | 7605 | types_match_const_cast_only(cur_type->data.maybe.child_type, prev_type)) |
| 7566 | 7606 | { |
| 7567 | 7607 | prev_inst = cur_inst; |
| 7568 | 7608 | continue; |
| 7569 | | } else if (cur_type->id == TypeTableEntryIdUndefLit) { |
| 7609 | } |
| 7610 | |
| 7611 | if (cur_type->id == TypeTableEntryIdUndefLit) { |
| 7570 | 7612 | continue; |
| 7571 | | } else if (prev_type->id == TypeTableEntryIdUndefLit) { |
| 7613 | } |
| 7614 | |
| 7615 | if (prev_type->id == TypeTableEntryIdUndefLit) { |
| 7572 | 7616 | prev_inst = cur_inst; |
| 7573 | 7617 | continue; |
| 7574 | | } else if (prev_type->id == TypeTableEntryIdNumLitInt || |
| 7618 | } |
| 7619 | |
| 7620 | if (prev_type->id == TypeTableEntryIdNumLitInt || |
| 7575 | 7621 | prev_type->id == TypeTableEntryIdNumLitFloat) |
| 7576 | 7622 | { |
| 7577 | 7623 | if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { |
| ... | ... | @@ -7580,7 +7626,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7580 | 7626 | } else { |
| 7581 | 7627 | return ira->codegen->builtin_types.entry_invalid; |
| 7582 | 7628 | } |
| 7583 | | } else if (cur_type->id == TypeTableEntryIdNumLitInt || |
| 7629 | } |
| 7630 | |
| 7631 | if (cur_type->id == TypeTableEntryIdNumLitInt || |
| 7584 | 7632 | cur_type->id == TypeTableEntryIdNumLitFloat) |
| 7585 | 7633 | { |
| 7586 | 7634 | if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { |
| ... | ... | @@ -7588,20 +7636,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7588 | 7636 | } else { |
| 7589 | 7637 | return ira->codegen->builtin_types.entry_invalid; |
| 7590 | 7638 | } |
| 7591 | | } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 7639 | } |
| 7640 | |
| 7641 | if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 7592 | 7642 | cur_type->data.array.len != prev_type->data.array.len && |
| 7593 | 7643 | types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type)) |
| 7594 | 7644 | { |
| 7595 | 7645 | convert_to_const_slice = true; |
| 7596 | 7646 | prev_inst = cur_inst; |
| 7597 | 7647 | continue; |
| 7598 | | } else if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 7648 | } |
| 7649 | |
| 7650 | if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray && |
| 7599 | 7651 | cur_type->data.array.len != prev_type->data.array.len && |
| 7600 | 7652 | types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type)) |
| 7601 | 7653 | { |
| 7602 | 7654 | convert_to_const_slice = true; |
| 7603 | 7655 | continue; |
| 7604 | | } else if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) && |
| 7656 | } |
| 7657 | |
| 7658 | if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) && |
| 7605 | 7659 | (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || |
| 7606 | 7660 | cur_type->data.array.len == 0) && |
| 7607 | 7661 | types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, |
| ... | ... | @@ -7609,7 +7663,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7609 | 7663 | { |
| 7610 | 7664 | convert_to_const_slice = false; |
| 7611 | 7665 | continue; |
| 7612 | | } else if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) && |
| 7666 | } |
| 7667 | |
| 7668 | if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) && |
| 7613 | 7669 | (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || |
| 7614 | 7670 | prev_type->data.array.len == 0) && |
| 7615 | 7671 | types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, |
| ... | ... | @@ -7618,17 +7674,40 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7618 | 7674 | prev_inst = cur_inst; |
| 7619 | 7675 | convert_to_const_slice = false; |
| 7620 | 7676 | continue; |
| 7621 | | } else { |
| 7622 | | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 7623 | | buf_sprintf("incompatible types: '%s' and '%s'", |
| 7624 | | buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); |
| 7625 | | add_error_note(ira->codegen, msg, prev_inst->source_node, |
| 7626 | | buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); |
| 7627 | | add_error_note(ira->codegen, msg, cur_inst->source_node, |
| 7628 | | buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); |
| 7677 | } |
| 7629 | 7678 | |
| 7630 | | return ira->codegen->builtin_types.entry_invalid; |
| 7679 | if (prev_type->id == TypeTableEntryIdEnum && cur_type->id == TypeTableEntryIdUnion && |
| 7680 | (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) |
| 7681 | { |
| 7682 | type_ensure_zero_bits_known(ira->codegen, cur_type); |
| 7683 | if (type_is_invalid(cur_type)) |
| 7684 | return ira->codegen->builtin_types.entry_invalid; |
| 7685 | if (cur_type->data.unionation.tag_type == prev_type) { |
| 7686 | continue; |
| 7687 | } |
| 7688 | } |
| 7689 | |
| 7690 | if (cur_type->id == TypeTableEntryIdEnum && prev_type->id == TypeTableEntryIdUnion && |
| 7691 | (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) |
| 7692 | { |
| 7693 | type_ensure_zero_bits_known(ira->codegen, prev_type); |
| 7694 | if (type_is_invalid(prev_type)) |
| 7695 | return ira->codegen->builtin_types.entry_invalid; |
| 7696 | if (prev_type->data.unionation.tag_type == cur_type) { |
| 7697 | prev_inst = cur_inst; |
| 7698 | continue; |
| 7699 | } |
| 7631 | 7700 | } |
| 7701 | |
| 7702 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| 7703 | buf_sprintf("incompatible types: '%s' and '%s'", |
| 7704 | buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); |
| 7705 | add_error_note(ira->codegen, msg, prev_inst->source_node, |
| 7706 | buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); |
| 7707 | add_error_note(ira->codegen, msg, cur_inst->source_node, |
| 7708 | buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); |
| 7709 | |
| 7710 | return ira->codegen->builtin_types.entry_invalid; |
| 7632 | 7711 | } |
| 7633 | 7712 | if (convert_to_const_slice) { |
| 7634 | 7713 | assert(prev_inst->value.type->id == TypeTableEntryIdArray); |
| ... | ... | @@ -9425,6 +9504,10 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 9425 | 9504 | TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, instructions, 2); |
| 9426 | 9505 | if (type_is_invalid(resolved_type)) |
| 9427 | 9506 | return resolved_type; |
| 9507 | type_ensure_zero_bits_known(ira->codegen, resolved_type); |
| 9508 | if (type_is_invalid(resolved_type)) |
| 9509 | return resolved_type; |
| 9510 | |
| 9428 | 9511 | |
| 9429 | 9512 | AstNode *source_node = bin_op_instruction->base.source_node; |
| 9430 | 9513 | switch (resolved_type->id) { |
| ... | ... | @@ -9489,7 +9572,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 9489 | 9572 | |
| 9490 | 9573 | ConstExprValue *op1_val = &casted_op1->value; |
| 9491 | 9574 | ConstExprValue *op2_val = &casted_op2->value; |
| 9492 | | if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) { |
| 9575 | bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type); |
| 9576 | if (one_possible_value || (value_is_comptime(op1_val) && value_is_comptime(op2_val))) { |
| 9493 | 9577 | bool answer; |
| 9494 | 9578 | if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) { |
| 9495 | 9579 | Cmp cmp_result = float_cmp(op1_val, op2_val); |
| ... | ... | @@ -9498,7 +9582,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 9498 | 9582 | Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 9499 | 9583 | answer = resolve_cmp_op_id(op_id, cmp_result); |
| 9500 | 9584 | } else { |
| 9501 | | bool are_equal = resolved_type->id == TypeTableEntryIdVoid || const_values_equal(op1_val, op2_val); |
| 9585 | bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val); |
| 9502 | 9586 | if (op_id == IrBinOpCmpEq) { |
| 9503 | 9587 | answer = are_equal; |
| 9504 | 9588 | } else if (op_id == IrBinOpCmpNotEq) { |
| ... | ... | @@ -13090,6 +13174,16 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 13090 | 13174 | return tag_type; |
| 13091 | 13175 | } |
| 13092 | 13176 | case TypeTableEntryIdEnum: { |
| 13177 | type_ensure_zero_bits_known(ira->codegen, target_type); |
| 13178 | if (type_is_invalid(target_type)) |
| 13179 | return ira->codegen->builtin_types.entry_invalid; |
| 13180 | if (target_type->data.enumeration.src_field_count < 2) { |
| 13181 | TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; |
| 13182 | ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); |
| 13183 | bigint_init_bigint(&out_val->data.x_enum_tag, &only_field->value); |
| 13184 | return target_type; |
| 13185 | } |
| 13186 | |
| 13093 | 13187 | if (pointee_val) { |
| 13094 | 13188 | ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base); |
| 13095 | 13189 | bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_enum_tag); |