| author | |
| committer | |
| log | cc17b662e48e43d134549ae5e986abe2e7db2822 |
| tree | 64c287ecaa26f47b05f06fee0b234c9c18ab0eb9 |
| parent | ffb3b1576b1c02942bce89ef05eaf05fe2f026ac |
| parent | b517bea734c0141fcda6b267a8f0de34cddc65f8 |
| signature |
3 files changed, 42 insertions(+), 9 deletions(-)
src/ir.cpp+14| ... | ... | @@ -18497,6 +18497,20 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns |
| 18497 | 18497 | if (type_is_invalid(target->value.type)) |
| 18498 | 18498 | return ira->codegen->builtin_types.entry_invalid; |
| 18499 | 18499 | |
| 18500 | if (target->value.type->id == TypeTableEntryIdComptimeInt) { | |
| 18501 | IrInstruction *casted_value = ir_implicit_cast(ira, target, dest_type); | |
| 18502 | if (type_is_invalid(casted_value->value.type)) | |
| 18503 | return ira->codegen->builtin_types.entry_invalid; | |
| 18504 | ir_link_new_instruction(casted_value, &instruction->base); | |
| 18505 | return casted_value->value.type; | |
| 18506 | } | |
| 18507 | ||
| 18508 | if (target->value.type->id != TypeTableEntryIdFloat && target->value.type->id != TypeTableEntryIdComptimeFloat) { | |
| 18509 | ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", | |
| 18510 | buf_ptr(&target->value.type->name))); | |
| 18511 | return ira->codegen->builtin_types.entry_invalid; | |
| 18512 | } | |
| 18513 | ||
| 18500 | 18514 | IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); |
| 18501 | 18515 | ir_link_new_instruction(result, &instruction->base); |
| 18502 | 18516 | return dest_type; |
test/cases/cast.zig+1| ... | ... | @@ -356,6 +356,7 @@ fn testFloatToInts() void { |
| 356 | 356 | expectFloatToInt(f32, 255.1, u8, 255); |
| 357 | 357 | expectFloatToInt(f32, 127.2, i8, 127); |
| 358 | 358 | expectFloatToInt(f32, -128.2, i8, -128); |
| 359 | expectFloatToInt(comptime_int, 1234, i16, 1234); | |
| 359 | 360 | } |
| 360 | 361 | |
| 361 | 362 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void { |
test/compile_errors.zig+27-9| ... | ... | @@ -1,6 +1,33 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.add( | |
| 5 | "non int passed to @intToFloat", | |
| 6 | \\export fn entry() void { | |
| 7 | \\ const x = @intToFloat(f32, 1.1); | |
| 8 | \\} | |
| 9 | , | |
| 10 | ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'", | |
| 11 | ); | |
| 12 | ||
| 13 | cases.add( | |
| 14 | "non float passed to @floatToInt", | |
| 15 | \\export fn entry() void { | |
| 16 | \\ const x = @floatToInt(i32, i32(54)); | |
| 17 | \\} | |
| 18 | , | |
| 19 | ".tmp_source.zig:2:35: error: expected float type, found 'i32'", | |
| 20 | ); | |
| 21 | ||
| 22 | cases.add( | |
| 23 | "out of range comptime_int passed to @floatToInt", | |
| 24 | \\export fn entry() void { | |
| 25 | \\ const x = @floatToInt(i8, 200); | |
| 26 | \\} | |
| 27 | , | |
| 28 | ".tmp_source.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'", | |
| 29 | ); | |
| 30 | ||
| 4 | 31 | cases.add( |
| 5 | 32 | "load too many bytes from comptime reinterpreted pointer", |
| 6 | 33 | \\export fn entry() void { |
| ... | ... | @@ -486,15 +513,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 486 | 513 | ".tmp_source.zig:2:20: error: return type cannot be opaque", |
| 487 | 514 | ); |
| 488 | 515 | |
| 489 | cases.add( | |
| 490 | "non int passed to @intToFloat", | |
| 491 | \\export fn entry() void { | |
| 492 | \\ const x = @intToFloat(f32, 1.1); | |
| 493 | \\} | |
| 494 | , | |
| 495 | ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'", | |
| 496 | ); | |
| 497 | ||
| 498 | 516 | cases.add( |
| 499 | 517 | "use implicit casts to assign null to non-nullable pointer", |
| 500 | 518 | \\export fn entry() void { |