diff --git a/src/ir.cpp b/src/ir.cpp index 4ce988e68..f7bfba6a9 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15537,6 +15537,26 @@ static bool ir_result_has_type(ResultLoc *result_loc) { zig_unreachable(); } +static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr, + ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime) +{ + Error err; + + IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); + if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, + PtrLenSingle, 0, 0, 0, false); + set_up_result_loc_for_inferred_comptime(&alloca_gen->base); + ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); + if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { + fn_entry->alloca_gen_list.append(alloca_gen); + } + result_loc->written = true; + result_loc->resolved_loc = &alloca_gen->base; + return result_loc->resolved_loc; +} + // when calling this function, at the callsite must check for result type noreturn and propagate it up static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) @@ -15559,19 +15579,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return nullptr; } // need to return a result location and don't have one. use a stack allocation - IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); - if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown))) - return ira->codegen->invalid_instruction; - alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, - PtrLenSingle, 0, 0, 0, false); - set_up_result_loc_for_inferred_comptime(&alloca_gen->base); - ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); - if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { - fn_entry->alloca_gen_list.append(alloca_gen); - } - result_loc->written = true; - result_loc->resolved_loc = &alloca_gen->base; - return result_loc->resolved_loc; + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); } case ResultLocIdVar: { ResultLocVar *result_loc_var = reinterpret_cast(result_loc); @@ -15710,6 +15719,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } case ResultLocIdCast: { + if (!non_null_comptime && value != nullptr && value->value.special != ConstValSpecialRuntime) + return nullptr; ResultLocCast *result_cast = reinterpret_cast(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) @@ -15720,9 +15731,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (const_cast_result.id == ConstCastResultIdInvalid) return ira->codegen->invalid_instruction; if (const_cast_result.id != ConstCastResultIdOk) { - // We will not be able to provide a result location for this value. Allow the - // code to create a new result location and then type coerce to the old one. - return nullptr; + // We will not be able to provide a result location for this value. Create + // a new result location. + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); } // In this case we can pointer cast the result location. @@ -15755,6 +15767,9 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { return ira->codegen->invalid_instruction; } + if (!type_has_bits(value_type)) { + parent_ptr_align = 0; + } ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index d786090dc..d0d38d844 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -1,7 +1,7 @@ comptime { _ = @import("behavior/align.zig"); _ = @import("behavior/alignof.zig"); - //_ = @import("behavior/array.zig"); + _ = @import("behavior/array.zig"); _ = @import("behavior/asm.zig"); _ = @import("behavior/async_fn.zig"); _ = @import("behavior/atomics.zig"); @@ -50,7 +50,7 @@ comptime { _ = @import("behavior/bugs/920.zig"); _ = @import("behavior/byteswap.zig"); _ = @import("behavior/byval_arg_var.zig"); - //_ = @import("behavior/cast.zig"); + _ = @import("behavior/cast.zig"); _ = @import("behavior/const_slice_child.zig"); _ = @import("behavior/defer.zig"); _ = @import("behavior/enum.zig"); diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index c4fcbce0c..98d987a73 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -75,8 +75,8 @@ test "peer resolve array and const slice" { comptime testPeerResolveArrayConstSlice(true); } fn testPeerResolveArrayConstSlice(b: bool) void { - const value1 = if (b) "aoeu" else ([]const u8)("zz"); - const value2 = if (b) ([]const u8)("zz") else "aoeu"; + const value1 = if (b) "aoeu" else @as([]const u8, "zz"); + const value2 = if (b) @as([]const u8, "zz") else "aoeu"; expect(mem.eql(u8, value1, "aoeu")); expect(mem.eql(u8, value2, "zz")); } @@ -258,7 +258,7 @@ test "@floatToInt" { fn testFloatToInts() void { const x = @as(i32, 1e4); expect(x == 10000); - const y = @floatToInt(i32, f32(1e4)); + const y = @floatToInt(i32, @as(f32, 1e4)); expect(y == 10000); expectFloatToInt(f16, 255.1, u8, 255); expectFloatToInt(f16, 127.2, i8, 127); @@ -392,7 +392,7 @@ fn MakeType(comptime T: type) type { } fn getNonNull() ?T { - return T(undefined); + return @as(T, undefined); } }; } @@ -535,12 +535,12 @@ test "peer type resolution: unreachable, error set, unreachable" { } test "implicit cast comptime_int to comptime_float" { - comptime expect(comptime_float(10) == f32(10)); + comptime expect(@as(comptime_float, 10) == @as(f32, 10)); expect(2 == 2.0); } test "implicit cast *[0]T to E![]const u8" { - var x = (anyerror![]const u8)(&[0]u8{}); + var x = @as(anyerror![]const u8, &[0]u8{}); expect((x catch unreachable).len == 0); }