Commit b517bea734

Andrew Kelley <superjoe30@gmail.com>
2018-09-06 00:01:48
allow comptime_int to @floatToInt
1 parent 768d1fc
Changed files (3)
src/ir.cpp
@@ -18497,6 +18497,14 @@ static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrIns
     if (type_is_invalid(target->value.type))
         return ira->codegen->builtin_types.entry_invalid;
 
+    if (target->value.type->id == TypeTableEntryIdComptimeInt) {
+        IrInstruction *casted_value = ir_implicit_cast(ira, target, dest_type);
+        if (type_is_invalid(casted_value->value.type))
+            return ira->codegen->builtin_types.entry_invalid;
+        ir_link_new_instruction(casted_value, &instruction->base);
+        return casted_value->value.type;
+    }
+
     if (target->value.type->id != TypeTableEntryIdFloat && target->value.type->id != TypeTableEntryIdComptimeFloat) {
         ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'",
                     buf_ptr(&target->value.type->name)));
test/cases/cast.zig
@@ -356,6 +356,7 @@ fn testFloatToInts() void {
     expectFloatToInt(f32, 255.1, u8, 255);
     expectFloatToInt(f32, 127.2, i8, 127);
     expectFloatToInt(f32, -128.2, i8, -128);
+    expectFloatToInt(comptime_int, 1234, i16, 1234);
 }
 
 fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void {
test/compile_errors.zig
@@ -1,6 +1,33 @@
 const tests = @import("tests.zig");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add(
+        "non int passed to @intToFloat",
+        \\export fn entry() void {
+        \\    const x = @intToFloat(f32, 1.1);
+        \\}
+    ,
+        ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'",
+    );
+
+    cases.add(
+        "non float passed to @floatToInt",
+        \\export fn entry() void {
+        \\    const x = @floatToInt(i32, i32(54));
+        \\}
+    ,
+        ".tmp_source.zig:2:35: error: expected float type, found 'i32'",
+    );
+
+    cases.add(
+        "out of range comptime_int passed to @floatToInt",
+        \\export fn entry() void {
+        \\    const x = @floatToInt(i8, 200);
+        \\}
+    ,
+        ".tmp_source.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'",
+    );
+
     cases.add(
         "load too many bytes from comptime reinterpreted pointer",
         \\export fn entry() void {
@@ -486,24 +513,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         ".tmp_source.zig:2:20: error: return type cannot be opaque",
     );
 
-    cases.add(
-        "non int passed to @intToFloat",
-        \\export fn entry() void {
-        \\    const x = @intToFloat(f32, 1.1);
-        \\}
-    ,
-        ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'",
-    );
-
-    cases.add(
-        "non float passed to @floatToInt",
-        \\export fn entry() void {
-        \\    const x = @floatToInt(i32, 54);
-        \\}
-    ,
-        ".tmp_source.zig:2:32: error: expected float type, found 'comptime_int'",
-    );
-
     cases.add(
         "use implicit casts to assign null to non-nullable pointer",
         \\export fn entry() void {