| author | |
| committer | |
| log | 2c434cddd6624cfd5c71f081b9445936d25c7703 |
| tree | b7512d9b316275efeff0c93fb034b47ae045d6d5 |
| parent | d4a0d5f959b88ffc23edc4593bc75b6168acaea9 |
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 { |
| 303 | 303 | ||
| 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 expression | 306 | 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; |
| 2764 | 2764 | ||
| 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 | |||
| 770 | test "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 | } |