From 2c434cddd6624cfd5c71f081b9445936d25c7703 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 15 Mar 2022 16:41:10 -0700 Subject: [PATCH] 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. --- lib/std/special/compiler_rt.zig | 6 ++---- src/AstGen.zig | 11 +++++++++-- test/behavior/eval.zig | 11 +++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 6819fe784d..3941918c47 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -303,10 +303,8 @@ comptime { const __floatunsisf = @import("compiler_rt/floatunsisf.zig").__floatunsisf; @export(__floatunsisf, .{ .name = "__floatunsisf", .linkage = linkage }); - if (builtin.zig_backend == .stage1) { // TODO it's crashing on a switch expression - const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf; - @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage }); - } + const __floatundisf = @import("compiler_rt/floatundisf.zig").__floatundisf; + @export(__floatundisf, .{ .name = "__floatundisf", .linkage = linkage }); const __floatunsidf = @import("compiler_rt/floatunsidf.zig").__floatunsidf; @export(__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage }); const __floatundidf = @import("compiler_rt/floatundidf.zig").__floatundidf; diff --git a/src/AstGen.zig b/src/AstGen.zig index 646560fd5a..c3e94ef631 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2762,11 +2762,18 @@ fn varDecl( } gz.instructions.items.len = dst; + // In case the result location did not do the coercion + // for us so we must do it here. + const coerced_init = if (opt_type_inst != .none) + try gz.addBin(.as, opt_type_inst, init_inst) + else + init_inst; + if (!gz.force_comptime) { _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{ .str_op = .{ .str = ident_name, - .operand = init_inst, + .operand = coerced_init, }, } }); } @@ -2776,7 +2783,7 @@ fn varDecl( .parent = scope, .gen_zir = gz, .name = ident_name, - .inst = init_inst, + .inst = coerced_init, .token_src = name_token, .id_cat = .@"local constant", }; diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 1847953550..fcb9d2f31f 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -766,3 +766,14 @@ test "two comptime calls with array default initialized to undefined" { S.CrossTarget.parse(); } } + +test "const type-annotated local initialized with function call has correct type" { + const S = struct { + fn foo() comptime_int { + return 1234; + } + }; + const x: u64 = S.foo(); + try expect(@TypeOf(x) == u64); + try expect(x == 1234); +}