| author | |
| committer | |
| log | 2e037fd827487ce94ae0beb313a1f0536085d61e |
| tree | 273cedc57f162c4ece5c09788dfd3d6bb3d39171 |
| parent | eddc68ad9470730a2742084a29ab08fa5363c754 |
3 files changed, 44 insertions(+), 21 deletions(-)
src/ir.cpp+13-7| ... | ... | @@ -13020,7 +13020,11 @@ static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGe |
| 13020 | 13020 | { |
| 13021 | 13021 | if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) { |
| 13022 | 13022 | IrInstGen *result = ir_const(ira, source_instr, wanted_type); |
| 13023 | if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, | |
| 13023 | ZigValue *val = ir_resolve_const(ira, value, UndefBad); | |
| 13024 | if (val == nullptr) | |
| 13025 | return ira->codegen->invalid_inst_gen; | |
| 13026 | ||
| 13027 | if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, val, val->type, | |
| 13024 | 13028 | result->value, wanted_type)) |
| 13025 | 13029 | { |
| 13026 | 13030 | return ira->codegen->invalid_inst_gen; |
| ... | ... | @@ -26680,6 +26684,10 @@ static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCa |
| 26680 | 26684 | } |
| 26681 | 26685 | |
| 26682 | 26686 | if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) { |
| 26687 | ZigValue *val = ir_resolve_const(ira, target, UndefBad); | |
| 26688 | if (val == nullptr) | |
| 26689 | return ira->codegen->invalid_inst_gen; | |
| 26690 | ||
| 26683 | 26691 | return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); |
| 26684 | 26692 | } |
| 26685 | 26693 | |
| ... | ... | @@ -26718,13 +26726,11 @@ static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFlo |
| 26718 | 26726 | } |
| 26719 | 26727 | |
| 26720 | 26728 | if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) { |
| 26721 | return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); | |
| 26722 | } | |
| 26729 | ZigValue *val = ir_resolve_const(ira, target, UndefBad); | |
| 26730 | if (val == nullptr) | |
| 26731 | return ira->codegen->invalid_inst_gen; | |
| 26723 | 26732 | |
| 26724 | if (target->value->type->id != ZigTypeIdFloat) { | |
| 26725 | ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", | |
| 26726 | buf_ptr(&target->value->type->name))); | |
| 26727 | return ira->codegen->invalid_inst_gen; | |
| 26733 | return ir_analyze_widen_or_shorten(ira, &instruction->target->base, target, dest_type); | |
| 26728 | 26734 | } |
| 26729 | 26735 | |
| 26730 | 26736 | return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); |
test/compile_errors.zig+18-14| ... | ... | @@ -2,6 +2,22 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const std = @import("std"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("int/float conversion to comptime_int/float", | |
| 6 | \\export fn foo() void { | |
| 7 | \\ var a: f32 = 2; | |
| 8 | \\ _ = @floatToInt(comptime_int, a); | |
| 9 | \\} | |
| 10 | \\export fn bar() void { | |
| 11 | \\ var a: u32 = 2; | |
| 12 | \\ _ = @intToFloat(comptime_float, a); | |
| 13 | \\} | |
| 14 | , &[_][]const u8{ | |
| 15 | "tmp.zig:3:35: error: unable to evaluate constant expression", | |
| 16 | "tmp.zig:3:9: note: referenced here", | |
| 17 | "tmp.zig:7:37: error: unable to evaluate constant expression", | |
| 18 | "tmp.zig:7:9: note: referenced here", | |
| 19 | }); | |
| 20 | ||
| 5 | 21 | cases.add("extern variable has no type", |
| 6 | 22 | \\extern var foo; |
| 7 | 23 | \\pub export fn entry() void { |
| ... | ... | @@ -90,19 +106,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 90 | 106 | \\ var a: u32 = 2; |
| 91 | 107 | \\ _ = @floatToInt(u32, a); |
| 92 | 108 | \\} |
| 93 | \\export fn qux() void { | |
| 94 | \\ var a: u32 = 2; | |
| 95 | \\ _ = @intCast(comptime_int, a); | |
| 96 | \\} | |
| 97 | 109 | , &[_][]const u8{ |
| 98 | "tmp.zig:3:32: error: expected type 'comptime_int', found 'u32'", | |
| 110 | "tmp.zig:3:32: error: unable to evaluate constant expression", | |
| 99 | 111 | "tmp.zig:3:9: note: referenced here", |
| 100 | 112 | "tmp.zig:7:21: error: expected float type, found 'u32'", |
| 101 | 113 | "tmp.zig:7:9: note: referenced here", |
| 102 | 114 | "tmp.zig:11:26: error: expected float type, found 'u32'", |
| 103 | 115 | "tmp.zig:11:9: note: referenced here", |
| 104 | "tmp.zig:15:32: error: expected type 'comptime_int', found 'u32'", | |
| 105 | "tmp.zig:15:9: note: referenced here", | |
| 106 | 116 | }); |
| 107 | 117 | |
| 108 | 118 | cases.addTest("invalid float casts", |
| ... | ... | @@ -118,19 +128,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 118 | 128 | \\ var a: f32 = 2; |
| 119 | 129 | \\ _ = @intToFloat(f32, a); |
| 120 | 130 | \\} |
| 121 | \\export fn qux() void { | |
| 122 | \\ var a: f32 = 2; | |
| 123 | \\ _ = @floatCast(comptime_float, a); | |
| 124 | \\} | |
| 125 | 131 | , &[_][]const u8{ |
| 126 | "tmp.zig:3:36: error: expected type 'comptime_float', found 'f32'", | |
| 132 | "tmp.zig:3:36: error: unable to evaluate constant expression", | |
| 127 | 133 | "tmp.zig:3:9: note: referenced here", |
| 128 | 134 | "tmp.zig:7:21: error: expected integer type, found 'f32'", |
| 129 | 135 | "tmp.zig:7:9: note: referenced here", |
| 130 | 136 | "tmp.zig:11:26: error: expected int type, found 'f32'", |
| 131 | 137 | "tmp.zig:11:9: note: referenced here", |
| 132 | "tmp.zig:15:36: error: expected type 'comptime_float', found 'f32'", | |
| 133 | "tmp.zig:15:9: note: referenced here", | |
| 134 | 138 | }); |
| 135 | 139 | |
| 136 | 140 | cases.addTest("invalid assignments", |
test/stage1/behavior/cast.zig+13| ... | ... | @@ -384,6 +384,19 @@ test "@intCast i32 to u7" { |
| 384 | 384 | expect(z == 0xff); |
| 385 | 385 | } |
| 386 | 386 | |
| 387 | test "@floatCast cast down" { | |
| 388 | { | |
| 389 | var double: f64 = 0.001534; | |
| 390 | var single = @floatCast(f32, double); | |
| 391 | expect(single == 0.001534); | |
| 392 | } | |
| 393 | { | |
| 394 | const double: f64 = 0.001534; | |
| 395 | const single = @floatCast(f32, double); | |
| 396 | expect(single == 0.001534); | |
| 397 | } | |
| 398 | } | |
| 399 | ||
| 387 | 400 | test "implicit cast undefined to optional" { |
| 388 | 401 | expect(MakeType(void).getNull() == null); |
| 389 | 402 | expect(MakeType(void).getNonNull() != null); |