diff --git a/src/ir.cpp b/src/ir.cpp index a45455ad39..ca0fd47c49 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13020,7 +13020,11 @@ static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGe { if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) { IrInstGen *result = ir_const(ira, source_instr, wanted_type); - if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, + ZigValue *val = ir_resolve_const(ira, value, UndefBad); + if (val == nullptr) + return ira->codegen->invalid_inst_gen; + + if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, val, val->type, result->value, wanted_type)) { return ira->codegen->invalid_inst_gen; @@ -26680,6 +26684,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa } if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) { + ZigValue *val = ir_resolve_const(ira, target, UndefBad); + if (val == nullptr) + return ira->codegen->invalid_inst_gen; + return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); } @@ -26718,13 +26726,11 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo } if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) { - return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); - } + ZigValue *val = ir_resolve_const(ira, target, UndefBad); + if (val == nullptr) + return ira->codegen->invalid_inst_gen; - if (target->value->type->id != ZigTypeIdFloat) { - ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", - buf_ptr(&target->value->type->name))); - return ira->codegen->invalid_inst_gen; + return ir_analyze_widen_or_shorten(ira, &instruction->target->base, target, dest_type); } return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 611094c050..df2e759bf1 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,22 @@ const tests = @import("tests.zig"); const std = @import("std"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("int/float conversion to comptime_int/float", + \\export fn foo() void { + \\ var a: f32 = 2; + \\ _ = @floatToInt(comptime_int, a); + \\} + \\export fn bar() void { + \\ var a: u32 = 2; + \\ _ = @intToFloat(comptime_float, a); + \\} + , &[_][]const u8{ + "tmp.zig:3:35: error: unable to evaluate constant expression", + "tmp.zig:3:9: note: referenced here", + "tmp.zig:7:37: error: unable to evaluate constant expression", + "tmp.zig:7:9: note: referenced here", + }); + cases.add("extern variable has no type", \\extern var foo; \\pub export fn entry() void { @@ -90,19 +106,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var a: u32 = 2; \\ _ = @floatToInt(u32, a); \\} - \\export fn qux() void { - \\ var a: u32 = 2; - \\ _ = @intCast(comptime_int, a); - \\} , &[_][]const u8{ - "tmp.zig:3:32: error: expected type 'comptime_int', found 'u32'", + "tmp.zig:3:32: error: unable to evaluate constant expression", "tmp.zig:3:9: note: referenced here", "tmp.zig:7:21: error: expected float type, found 'u32'", "tmp.zig:7:9: note: referenced here", "tmp.zig:11:26: error: expected float type, found 'u32'", "tmp.zig:11:9: note: referenced here", - "tmp.zig:15:32: error: expected type 'comptime_int', found 'u32'", - "tmp.zig:15:9: note: referenced here", }); cases.addTest("invalid float casts", @@ -118,19 +128,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ var a: f32 = 2; \\ _ = @intToFloat(f32, a); \\} - \\export fn qux() void { - \\ var a: f32 = 2; - \\ _ = @floatCast(comptime_float, a); - \\} , &[_][]const u8{ - "tmp.zig:3:36: error: expected type 'comptime_float', found 'f32'", + "tmp.zig:3:36: error: unable to evaluate constant expression", "tmp.zig:3:9: note: referenced here", "tmp.zig:7:21: error: expected integer type, found 'f32'", "tmp.zig:7:9: note: referenced here", "tmp.zig:11:26: error: expected int type, found 'f32'", "tmp.zig:11:9: note: referenced here", - "tmp.zig:15:36: error: expected type 'comptime_float', found 'f32'", - "tmp.zig:15:9: note: referenced here", }); cases.addTest("invalid assignments", diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 77cdacc307..4b678cd2db 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -384,6 +384,19 @@ test "@intCast i32 to u7" { expect(z == 0xff); } +test "@floatCast cast down" { + { + var double: f64 = 0.001534; + var single = @floatCast(f32, double); + expect(single == 0.001534); + } + { + const double: f64 = 0.001534; + const single = @floatCast(f32, double); + expect(single == 0.001534); + } +} + test "implicit cast undefined to optional" { expect(MakeType(void).getNull() == null); expect(MakeType(void).getNonNull() != null);