@@ -570,6 +570,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
570
570
return buf_create_from_str (" attempt to unwrap error" );
571
571
case PanicMsgIdUnreachable:
572
572
return buf_create_from_str (" reached unreachable code" );
573
+ case PanicMsgIdInvalidErrorCode:
574
+ return buf_create_from_str (" invalid error code" );
573
575
}
574
576
zig_unreachable ();
575
577
}
@@ -1227,14 +1229,6 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
1227
1229
zig_unreachable ();
1228
1230
case CastOpNoop:
1229
1231
return expr_val;
1230
- case CastOpErrToInt:
1231
- assert (actual_type->id == TypeTableEntryIdErrorUnion);
1232
- if (!type_has_bits (actual_type->data .error .child_type )) {
1233
- return gen_widen_or_shorten (g, ir_want_debug_safety (g, &cast_instruction->base ),
1234
- g->err_tag_type , wanted_type, expr_val);
1235
- } else {
1236
- zig_panic (" TODO" );
1237
- }
1238
1232
case CastOpResizeSlice:
1239
1233
{
1240
1234
assert (cast_instruction->tmp_ptr );
@@ -1402,6 +1396,66 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
1402
1396
instruction->target ->value .type , wanted_int_type, target_val);
1403
1397
}
1404
1398
1399
+ static LLVMValueRef ir_render_int_to_err (CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) {
1400
+ TypeTableEntry *wanted_type = instruction->base .value .type ;
1401
+ assert (wanted_type->id == TypeTableEntryIdPureError);
1402
+
1403
+ TypeTableEntry *actual_type = instruction->target ->value .type ;
1404
+ assert (actual_type->id == TypeTableEntryIdInt);
1405
+ assert (!actual_type->data .integral .is_signed );
1406
+
1407
+ LLVMValueRef target_val = ir_llvm_value (g, instruction->target );
1408
+
1409
+ if (ir_want_debug_safety (g, &instruction->base )) {
1410
+ LLVMValueRef zero = LLVMConstNull (actual_type->type_ref );
1411
+ LLVMValueRef neq_zero_bit = LLVMBuildICmp (g->builder , LLVMIntNE, target_val, zero, " " );
1412
+ LLVMValueRef ok_bit;
1413
+ uint64_t biggest_possible_err_val = max_unsigned_val (actual_type);
1414
+ if (biggest_possible_err_val < g->error_decls .length ) {
1415
+ ok_bit = neq_zero_bit;
1416
+ } else {
1417
+ LLVMValueRef error_value_count = LLVMConstInt (actual_type->type_ref , g->error_decls .length , false );
1418
+ LLVMValueRef in_bounds_bit = LLVMBuildICmp (g->builder , LLVMIntULT, target_val, error_value_count, " " );
1419
+ ok_bit = LLVMBuildAnd (g->builder , neq_zero_bit, in_bounds_bit, " " );
1420
+ }
1421
+
1422
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock (g->cur_fn_val , " IntToErrOk" );
1423
+ LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock (g->cur_fn_val , " IntToErrFail" );
1424
+
1425
+ LLVMBuildCondBr (g->builder , ok_bit, ok_block, fail_block);
1426
+
1427
+ LLVMPositionBuilderAtEnd (g->builder , fail_block);
1428
+ gen_debug_safety_crash (g, PanicMsgIdInvalidErrorCode);
1429
+
1430
+ LLVMPositionBuilderAtEnd (g->builder , ok_block);
1431
+ }
1432
+
1433
+ return gen_widen_or_shorten (g, false , actual_type, g->err_tag_type , target_val);
1434
+ }
1435
+
1436
+ static LLVMValueRef ir_render_err_to_int (CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) {
1437
+ TypeTableEntry *wanted_type = instruction->base .value .type ;
1438
+ assert (wanted_type->id == TypeTableEntryIdInt);
1439
+ assert (!wanted_type->data .integral .is_signed );
1440
+
1441
+ TypeTableEntry *actual_type = instruction->target ->value .type ;
1442
+ LLVMValueRef target_val = ir_llvm_value (g, instruction->target );
1443
+
1444
+ if (actual_type->id == TypeTableEntryIdPureError) {
1445
+ return gen_widen_or_shorten (g, ir_want_debug_safety (g, &instruction->base ),
1446
+ g->err_tag_type , wanted_type, target_val);
1447
+ } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
1448
+ if (!type_has_bits (actual_type->data .error .child_type )) {
1449
+ return gen_widen_or_shorten (g, ir_want_debug_safety (g, &instruction->base ),
1450
+ g->err_tag_type , wanted_type, target_val);
1451
+ } else {
1452
+ zig_panic (" TODO" );
1453
+ }
1454
+ } else {
1455
+ zig_unreachable ();
1456
+ }
1457
+ }
1458
+
1405
1459
static LLVMValueRef ir_render_unreachable (CodeGen *g, IrExecutable *executable,
1406
1460
IrInstructionUnreachable *unreachable_instruction)
1407
1461
{
@@ -2786,6 +2840,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2786
2840
return ir_render_int_to_ptr (g, executable, (IrInstructionIntToPtr *)instruction);
2787
2841
case IrInstructionIdIntToEnum:
2788
2842
return ir_render_int_to_enum (g, executable, (IrInstructionIntToEnum *)instruction);
2843
+ case IrInstructionIdIntToErr:
2844
+ return ir_render_int_to_err (g, executable, (IrInstructionIntToErr *)instruction);
2845
+ case IrInstructionIdErrToInt:
2846
+ return ir_render_err_to_int (g, executable, (IrInstructionErrToInt *)instruction);
2789
2847
case IrInstructionIdContainerInitList:
2790
2848
return ir_render_container_init_list (g, executable, (IrInstructionContainerInitList *)instruction);
2791
2849
case IrInstructionIdPanic:
0 commit comments