Commit c026a9f6d2
Changed files (2)
src
src/ir.cpp
@@ -25957,16 +25957,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa
return ira->codegen->invalid_inst_gen;
}
- if (instr_is_comptime(target)) {
+ if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) {
return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type);
}
- if (dest_type->id == ZigTypeIdComptimeInt) {
- ir_add_error(ira, &instruction->target->base, buf_sprintf("attempt to cast runtime value to '%s'",
- buf_ptr(&dest_type->name)));
- return ira->codegen->invalid_inst_gen;
- }
-
return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type);
}
@@ -25975,7 +25969,7 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo
if (type_is_invalid(dest_type))
return ira->codegen->invalid_inst_gen;
- if (dest_type->id != ZigTypeIdFloat) {
+ if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) {
ir_add_error(ira, &instruction->dest_type->base,
buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_inst_gen;
@@ -26001,6 +25995,10 @@ 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);
+ }
+
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)));
@@ -26064,6 +26062,12 @@ static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcI
if (type_is_invalid(dest_type))
return ira->codegen->invalid_inst_gen;
+ if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) {
+ ir_add_error(ira, &instruction->dest_type->base,
+ buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_inst_gen;
+ }
+
IrInstGen *target = instruction->target->child;
if (type_is_invalid(target->value->type))
return ira->codegen->invalid_inst_gen;
@@ -26077,33 +26081,31 @@ static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcI
return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat);
}
-static IrInstGen *ir_analyze_float_to_int(IrAnalyze *ira, IrInst* source_instr,
- ZigType *dest_type, IrInstGen *operand, AstNode *operand_source_node)
-{
- if (operand->value->type->id == ZigTypeIdComptimeInt) {
- return ir_implicit_cast(ira, operand, dest_type);
- }
+static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) {
+ ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);
+ if (type_is_invalid(dest_type))
+ return ira->codegen->invalid_inst_gen;
- if (operand->value->type->id != ZigTypeIdFloat && operand->value->type->id != ZigTypeIdComptimeFloat) {
- ir_add_error_node(ira, operand_source_node, buf_sprintf("expected float type, found '%s'",
- buf_ptr(&operand->value->type->name)));
+ if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) {
+ ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_inst_gen;
}
- return ir_resolve_cast(ira, source_instr, operand, dest_type, CastOpFloatToInt);
-}
-
-static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) {
- ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);
- if (type_is_invalid(dest_type))
+ IrInstGen *target = instruction->target->child;
+ if (type_is_invalid(target->value->type))
return ira->codegen->invalid_inst_gen;
- IrInstGen *operand = instruction->target->child;
- if (type_is_invalid(operand->value->type))
+ if (target->value->type->id == ZigTypeIdComptimeInt) {
+ return ir_implicit_cast(ira, target, dest_type);
+ }
+
+ if (target->value->type->id != ZigTypeIdFloat && target->value->type->id != ZigTypeIdComptimeFloat) {
+ ir_add_error_node(ira, target->base.source_node, buf_sprintf("expected float type, found '%s'",
+ buf_ptr(&target->value->type->name)));
return ira->codegen->invalid_inst_gen;
+ }
- return ir_analyze_float_to_int(ira, &instruction->base.base, dest_type, operand,
- instruction->target->base.source_node);
+ return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpFloatToInt);
}
static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) {
test/compile_errors.zig
@@ -2,6 +2,62 @@ const tests = @import("tests.zig");
const std = @import("std");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest("invalid int casts",
+ \\export fn foo() void {
+ \\ var a: u32 = 2;
+ \\ _ = @intCast(comptime_int, a);
+ \\}
+ \\export fn bar() void {
+ \\ var a: u32 = 2;
+ \\ _ = @intToFloat(u32, a);
+ \\}
+ \\export fn baz() 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: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",
+ \\export fn foo() void {
+ \\ var a: f32 = 2;
+ \\ _ = @floatCast(comptime_float, a);
+ \\}
+ \\export fn bar() void {
+ \\ var a: f32 = 2;
+ \\ _ = @floatToInt(f32, a);
+ \\}
+ \\export fn baz() 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: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",
\\export fn entry1() void {
\\ var a: []const u8 = "foo";