From f8a782fb2ec63b89fadb409f7378066a26945d3b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 18 Nov 2018 19:36:27 -0500 Subject: [PATCH] all numbers with comptime known values implicitly cast to all number types. If the value does not fit, a compile error is emitted. closes #422 closes #1712 --- doc/langref.html.in | 4 +- src/ir.cpp | 406 +++++++++++++++++++++++++++------------- test/cases/cast.zig | 10 + test/compile_errors.zig | 87 ++++++--- 4 files changed, 346 insertions(+), 161 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index c3d8af4420..022b03ef40 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6659,7 +6659,7 @@ fn foo(x: []const u8) u8 { {#header_close#} {#header_open|Cast Negative Number to Unsigned Integer#}

At compile-time:

- {#code_begin|test_err|attempt to cast negative value to unsigned integer#} + {#code_begin|test_err|cannot cast negative value -1 to unsigned integer type 'u32'#} comptime { const value: i32 = -1; const unsigned = @intCast(u32, value); @@ -6681,7 +6681,7 @@ pub fn main() void { {#header_close#} {#header_open|Cast Truncates Data#}

At compile-time:

- {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} + {#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#} comptime { const spartan_count: u16 = 300; const byte = @intCast(u8, spartan_count); diff --git a/src/ir.cpp b/src/ir.cpp index 2c499e885d..3a22d0aa17 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -138,6 +138,11 @@ struct ConstCastErrSetMismatch { ZigList missing_errors; }; +enum UndefAllowed { + UndefOk, + UndefBad, +}; + static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); @@ -157,6 +162,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, ConstExprValue *out_val, ConstExprValue *ptr_val); static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, ZigType *dest_type, IrInstruction *dest_type_src); +static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -8063,15 +8069,153 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc return false; } - ConstExprValue *const_val = &instruction->value; - assert(const_val->special != ConstValSpecialRuntime); + ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); + assert(const_val != nullptr); + + bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); + bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); - bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || - const_val->type->id == ZigTypeIdComptimeInt); - bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || - const_val->type->id == ZigTypeIdComptimeFloat); if (other_type->id == ZigTypeIdFloat) { - return true; + if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { + return true; + } + if (const_val->type->id == ZigTypeIdInt) { + BigFloat tmp_bf; + bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); + BigFloat orig_bf; + switch (other_type->data.floating.bit_count) { + case 16: { + float16_t tmp = bigfloat_to_f16(&tmp_bf); + bigfloat_init_16(&orig_bf, tmp); + break; + } + case 32: { + float tmp = bigfloat_to_f32(&tmp_bf); + bigfloat_init_32(&orig_bf, tmp); + break; + } + case 64: { + double tmp = bigfloat_to_f64(&tmp_bf); + bigfloat_init_64(&orig_bf, tmp); + break; + } + case 80: + zig_panic("TODO"); + case 128: { + float128_t tmp = bigfloat_to_f128(&tmp_bf); + bigfloat_init_128(&orig_bf, tmp); + break; + } + default: + zig_unreachable(); + } + BigInt orig_bi; + bigint_init_bigfloat(&orig_bi, &orig_bf); + if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { + return true; + } + Buf *val_buf = buf_alloc(); + bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); + ir_add_error(ira, instruction, + buf_sprintf("integer value %s has no representation in type '%s'", + buf_ptr(val_buf), + buf_ptr(&other_type->name))); + return false; + } + if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { + return true; + } + switch (other_type->data.floating.bit_count) { + case 16: + switch (const_val->type->data.floating.bit_count) { + case 32: { + float16_t tmp = zig_double_to_f16(const_val->data.x_f32); + float orig = zig_f16_to_double(tmp); + if (const_val->data.x_f32 == orig) { + return true; + } + break; + } + case 64: { + float16_t tmp = zig_double_to_f16(const_val->data.x_f64); + double orig = zig_f16_to_double(tmp); + if (const_val->data.x_f64 == orig) { + return true; + } + break; + } + case 80: + zig_panic("TODO"); + case 128: { + float16_t tmp = f128M_to_f16(&const_val->data.x_f128); + float128_t orig; + f16_to_f128M(tmp, &orig); + if (f128M_eq(&orig, &const_val->data.x_f128)) { + return true; + } + break; + } + default: + zig_unreachable(); + } + break; + case 32: + switch (const_val->type->data.floating.bit_count) { + case 64: { + float tmp = const_val->data.x_f64; + double orig = tmp; + if (const_val->data.x_f64 == orig) { + return true; + } + break; + } + case 80: + zig_panic("TODO"); + case 128: { + float32_t tmp = f128M_to_f32(&const_val->data.x_f128); + float128_t orig; + f32_to_f128M(tmp, &orig); + if (f128M_eq(&orig, &const_val->data.x_f128)) { + return true; + } + break; + } + default: + zig_unreachable(); + } + break; + case 64: + switch (const_val->type->data.floating.bit_count) { + case 80: + zig_panic("TODO"); + case 128: { + float64_t tmp = f128M_to_f64(&const_val->data.x_f128); + float128_t orig; + f64_to_f128M(tmp, &orig); + if (f128M_eq(&orig, &const_val->data.x_f128)) { + return true; + } + break; + } + default: + zig_unreachable(); + } + break; + case 80: + assert(const_val->type->data.floating.bit_count == 128); + zig_panic("TODO"); + case 128: + return true; + default: + zig_unreachable(); + } + Buf *val_buf = buf_alloc(); + float_append_buf(val_buf, const_val); + ir_add_error(ira, instruction, + buf_sprintf("cast of value %s to type '%s' loses information", + buf_ptr(val_buf), + buf_ptr(&other_type->name))); + return false; } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { Buf *val_buf = buf_alloc(); @@ -9453,11 +9597,6 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio return const_instr; } -enum UndefAllowed { - UndefOk, - UndefBad, -}; - static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { switch (value->value.special) { case ConstValSpecialStatic: @@ -10370,6 +10509,121 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); } + // cast from T to ?T + // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism + if (wanted_type->id == ZigTypeIdOptional) { + ZigType *wanted_child_type = wanted_type->data.maybe.child_type; + if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, + false).id == ConstCastResultIdOk) + { + return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); + } else if (actual_type->id == ZigTypeIdComptimeInt || + actual_type->id == ZigTypeIdComptimeFloat) + { + if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { + return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); + } else { + return ira->codegen->invalid_instruction; + } + } else if ( + wanted_child_type->id == ZigTypeIdPointer && + wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && + actual_type->id == ZigTypeIdPointer && + actual_type->data.pointer.ptr_len == PtrLenSingle && + actual_type->data.pointer.child_type->id == ZigTypeIdArray) + { + if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + return ira->codegen->invalid_instruction; + if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) + return ira->codegen->invalid_instruction; + if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && + types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, + actual_type->data.pointer.child_type->data.array.child_type, source_node, + !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) + { + IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, + wanted_child_type); + if (type_is_invalid(cast1->value.type)) + return ira->codegen->invalid_instruction; + return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); + } + } + } + + // T to E!T + if (wanted_type->id == ZigTypeIdErrorUnion) { + if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, + source_node, false).id == ConstCastResultIdOk) + { + return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); + } else if (actual_type->id == ZigTypeIdComptimeInt || + actual_type->id == ZigTypeIdComptimeFloat) + { + if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { + return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); + } else { + return ira->codegen->invalid_instruction; + } + } + } + + // cast from T to E!?T + if (wanted_type->id == ZigTypeIdErrorUnion && + wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && + actual_type->id != ZigTypeIdOptional) + { + ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; + if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || + actual_type->id == ZigTypeIdNull || + actual_type->id == ZigTypeIdComptimeInt || + actual_type->id == ZigTypeIdComptimeFloat) + { + IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); + if (type_is_invalid(cast1->value.type)) + return ira->codegen->invalid_instruction; + + IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); + if (type_is_invalid(cast2->value.type)) + return ira->codegen->invalid_instruction; + + return cast2; + } + } + + + // cast from comptime-known number to another number type + if (instr_is_comptime(value) && + (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || + actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && + (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || + wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) + { + if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { + if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { + IrInstruction *result = ir_const(ira, source_instr, wanted_type); + if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { + bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint); + } else { + float_init_bigint(&result->value.data.x_bigint, &value->value); + } + return result; + } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { + IrInstruction *result = ir_const(ira, source_instr, wanted_type); + if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { + BigFloat bf; + bigfloat_init_bigint(&bf, &value->value.data.x_bigint); + float_init_bigfloat(&result->value, &bf); + } else { + float_init_float(&result->value, &value->value); + } + return result; + } + zig_unreachable(); + } else { + return ira->codegen->invalid_instruction; + } + } + // widening conversion if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt && @@ -10472,47 +10726,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } - // cast from T to ?T - // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism - if (wanted_type->id == ZigTypeIdOptional) { - ZigType *wanted_child_type = wanted_type->data.maybe.child_type; - if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, - false).id == ConstCastResultIdOk) - { - return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); - } else if (actual_type->id == ZigTypeIdComptimeInt || - actual_type->id == ZigTypeIdComptimeFloat) - { - if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { - return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); - } else { - return ira->codegen->invalid_instruction; - } - } else if ( - wanted_child_type->id == ZigTypeIdPointer && - wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && - actual_type->id == ZigTypeIdPointer && - actual_type->data.pointer.ptr_len == PtrLenSingle && - actual_type->data.pointer.child_type->id == ZigTypeIdArray) - { - if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; - if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) - return ira->codegen->invalid_instruction; - if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && - types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, - actual_type->data.pointer.child_type->data.array.child_type, source_node, - !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) - { - IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, - wanted_child_type); - if (type_is_invalid(cast1->value.type)) - return ira->codegen->invalid_instruction; - return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); - } - } - } - // cast from null literal to maybe type if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdNull) @@ -10520,23 +10733,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); } - // cast from child type of error type to error type - if (wanted_type->id == ZigTypeIdErrorUnion) { - if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, - source_node, false).id == ConstCastResultIdOk) - { - return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); - } else if (actual_type->id == ZigTypeIdComptimeInt || - actual_type->id == ZigTypeIdComptimeFloat) - { - if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { - return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); - } else { - return ira->codegen->invalid_instruction; - } - } - } - // cast from [N]T to E![]const T if (wanted_type->id == ZigTypeIdErrorUnion && is_slice(wanted_type->data.error_union.payload_type) && @@ -10568,54 +10764,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); } - // cast from T to E!?T - if (wanted_type->id == ZigTypeIdErrorUnion && - wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && - actual_type->id != ZigTypeIdOptional) - { - ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; - if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || - actual_type->id == ZigTypeIdNull || - actual_type->id == ZigTypeIdComptimeInt || - actual_type->id == ZigTypeIdComptimeFloat) - { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); - if (type_is_invalid(cast1->value.type)) - return ira->codegen->invalid_instruction; - - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); - if (type_is_invalid(cast2->value.type)) - return ira->codegen->invalid_instruction; - - return cast2; - } - } - - // cast from number literal to another type - if (actual_type->id == ZigTypeIdComptimeFloat || - actual_type->id == ZigTypeIdComptimeInt) - { - if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { - CastOp op; - if ((actual_type->id == ZigTypeIdComptimeFloat && - wanted_type->id == ZigTypeIdFloat) || - (actual_type->id == ZigTypeIdComptimeInt && - wanted_type->id == ZigTypeIdInt)) - { - op = CastOpNumLitToConcrete; - } else if (wanted_type->id == ZigTypeIdInt) { - op = CastOpFloatToInt; - } else if (wanted_type->id == ZigTypeIdFloat) { - op = CastOpIntToFloat; - } else { - zig_unreachable(); - } - return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false); - } else { - return ira->codegen->invalid_instruction; - } - } - // cast from typed number to integer or float literal. // works when the number is known at compile time if (instr_is_comptime(value) && @@ -17878,7 +18026,7 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; - if (dest_type->id != ZigTypeIdInt) { + if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); return ira->codegen->invalid_instruction; } @@ -17887,20 +18035,22 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct if (type_is_invalid(target->value.type)) return ira->codegen->invalid_instruction; - if (target->value.type->id == ZigTypeIdComptimeInt) { - if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { - return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpNumLitToConcrete, false); - } else { - return ira->codegen->invalid_instruction; - } - } - - if (target->value.type->id != ZigTypeIdInt) { + if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&target->value.type->name))); return ira->codegen->invalid_instruction; } + if (instr_is_comptime(target)) { + return ir_implicit_cast(ira, target, dest_type); + } + + if (dest_type->id == ZigTypeIdComptimeInt) { + ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", + buf_ptr(&dest_type->name))); + return ira->codegen->invalid_instruction; + } + return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); } diff --git a/test/cases/cast.zig b/test/cases/cast.zig index e893ec13cd..06c029a405 100644 --- a/test/cases/cast.zig +++ b/test/cases/cast.zig @@ -452,3 +452,13 @@ test "implicit ptr to *c_void" { var c: *u32 = @ptrCast(*u32, ptr2.?); assert(c.* == 1); } + +test "@intCast to comptime_int" { + assert(@intCast(comptime_int, 0) == 0); +} + +test "implicit cast comptime numbers to any type when the value fits" { + const a: u64 = 255; + var b: u8 = a; + assert(b == 255); +} diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 7339be7fad..45bd6cb40b 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1,6 +1,61 @@ const tests = @import("tests.zig"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "cast negative value to unsigned integer", + \\comptime { + \\ const value: i32 = -1; + \\ const unsigned = @intCast(u32, value); + \\} + \\export fn entry1() void { + \\ const value: i32 = -1; + \\ const unsigned: u32 = value; + \\} + , + ".tmp_source.zig:3:36: error: cannot cast negative value -1 to unsigned integer type 'u32'", + ".tmp_source.zig:7:27: error: cannot cast negative value -1 to unsigned integer type 'u32'", + ); + + cases.add( + "integer cast truncates bits", + \\export fn entry1() void { + \\ const spartan_count: u16 = 300; + \\ const byte = @intCast(u8, spartan_count); + \\} + \\export fn entry2() void { + \\ const spartan_count: u16 = 300; + \\ const byte: u8 = spartan_count; + \\} + \\export fn entry3() void { + \\ var spartan_count: u16 = 300; + \\ var byte: u8 = spartan_count; + \\} + , + ".tmp_source.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'", + ".tmp_source.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'", + ".tmp_source.zig:11:20: error: expected type 'u8', found 'u16'", + ); + + cases.add( + "comptime implicit cast f64 to f32", + \\export fn entry() void { + \\ const x: f64 = 16777217; + \\ const y: f32 = x; + \\} + , + ".tmp_source.zig:3:20: error: cast of value 16777217.000000 to type 'f32' loses information", + ); + + cases.add( + "implicit cast from f64 to f32", + \\var x: f64 = 1.0; + \\var y: f32 = x; + \\ + \\export fn entry() usize { return @sizeOf(@typeOf(y)); } + , + ".tmp_source.zig:2:14: error: expected type 'f32', found 'f64'", + ); + cases.add( "exceeded maximum bit width of integer", \\export fn entry1() void { @@ -1819,7 +1874,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ if (0) {} \\} , - ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'", + ".tmp_source.zig:2:9: error: expected type 'bool', found 'comptime_int'", ); cases.add( @@ -2422,16 +2477,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'", ); - cases.add( - "implicit cast from f64 to f32", - \\const x : f64 = 1.0; - \\const y : f32 = x; - \\ - \\export fn entry() usize { return @sizeOf(@typeOf(y)); } - , - ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'", - ); - cases.add( "colliding invalid top level functions", \\fn func() bogus {} @@ -4049,16 +4094,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod", ); - cases.add( - "cast negative value to unsigned integer", - \\comptime { - \\ const value: i32 = -1; - \\ const unsigned = @intCast(u32, value); - \\} - , - ".tmp_source.zig:3:22: error: attempt to cast negative value to unsigned integer", - ); - cases.add( "compile-time division by zero", \\comptime { @@ -4081,16 +4116,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { ".tmp_source.zig:4:17: error: division by zero", ); - cases.add( - "compile-time integer cast truncates bits", - \\comptime { - \\ const spartan_count: u16 = 300; - \\ const byte = @intCast(u8, spartan_count); - \\} - , - ".tmp_source.zig:3:18: error: cast from 'u16' to 'u8' truncates bits", - ); - cases.add( "@setRuntimeSafety twice for same scope", \\export fn foo() void {