authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 16:41:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 16:41:10-07:00
log2c434cddd6624cfd5c71f081b9445936d25c7703
treeb7512d9b316275efeff0c93fb034b47ae045d6d5
parentd4a0d5f959b88ffc23edc4593bc75b6168acaea9

AstGen: add missing coercion for const locals

A const local which had its init expression write to the result pointer, but then gets elided to directly initialize, was missing the coercion to the type annotation.

3 files changed, 22 insertions(+), 6 deletions(-)

lib/std/special/compiler_rt.zig+2-4
...@@ -303,10 +303,8 @@ comptime {...@@ -303,10 +303,8 @@ comptime {
303303
304 const __floatunsisf = @import("compiler_rt/floatunsisf.zig").__floatunsisf;304 const __floatunsisf = @import("compiler_rt/floatunsisf.zig").__floatunsisf;
305 @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });305 @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage });
306 if (builtin.zig_backend == .stage1) { // TODO it's crashing on a switch expression306 const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf;
307 const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf;307 @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
308 @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage });
309 }
310 const __floatunsidf = @import("compiler_rt/floatunsidf.zig").__floatunsidf;308 const __floatunsidf = @import("compiler_rt/floatunsidf.zig").__floatunsidf;
311 @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });309 @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage });
312 const __floatundidf = @import("compiler_rt/floatundidf.zig").__floatundidf;310 const __floatundidf = @import("compiler_rt/floatundidf.zig").__floatundidf;
src/AstGen.zig+9-2
...@@ -2762,11 +2762,18 @@ fn varDecl(...@@ -2762,11 +2762,18 @@ fn varDecl(
2762 }2762 }
2763 gz.instructions.items.len = dst;2763 gz.instructions.items.len = dst;
27642764
2765 // In case the result location did not do the coercion
2766 // for us so we must do it here.
2767 const coerced_init = if (opt_type_inst != .none)
2768 try gz.addBin(.as, opt_type_inst, init_inst)
2769 else
2770 init_inst;
2771
2765 if (!gz.force_comptime) {2772 if (!gz.force_comptime) {
2766 _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{2773 _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{
2767 .str_op = .{2774 .str_op = .{
2768 .str = ident_name,2775 .str = ident_name,
2769 .operand = init_inst,2776 .operand = coerced_init,
2770 },2777 },
2771 } });2778 } });
2772 }2779 }
...@@ -2776,7 +2783,7 @@ fn varDecl(...@@ -2776,7 +2783,7 @@ fn varDecl(
2776 .parent = scope,2783 .parent = scope,
2777 .gen_zir = gz,2784 .gen_zir = gz,
2778 .name = ident_name,2785 .name = ident_name,
2779 .inst = init_inst,2786 .inst = coerced_init,
2780 .token_src = name_token,2787 .token_src = name_token,
2781 .id_cat = .@"local constant",2788 .id_cat = .@"local constant",
2782 };2789 };
test/behavior/eval.zig+11
...@@ -766,3 +766,14 @@ test "two comptime calls with array default initialized to undefined" {...@@ -766,3 +766,14 @@ test "two comptime calls with array default initialized to undefined" {
766 S.CrossTarget.parse();766 S.CrossTarget.parse();
767 }767 }
768}768}
769
770test "const type-annotated local initialized with function call has correct type" {
771 const S = struct {
772 fn foo() comptime_int {
773 return 1234;
774 }
775 };
776 const x: u64 = S.foo();
777 try expect(@TypeOf(x) == u64);
778 try expect(x == 1234);
779}