mirror of
https://github.com/ziglang/zig.git
synced 2026-02-08 07:27:18 +00:00
AstGen: fix const locals with comptime initializations
`const foo = comptime ...` generated invalid ZIR when the initialization expression contained an array literal because the validate_array_init_comptime instruction assumed that the corresponding alloc instruction was comptime. The solution is to look slightly ahead and notice that the initialization expression would be comptime-known and affect the alloc instruction tag accordingly.
This commit is contained in:
parent
9a1d5001d4
commit
5c68afef94
@ -2671,6 +2671,9 @@ fn varDecl(
|
||||
return &sub_scope.base;
|
||||
}
|
||||
|
||||
const is_comptime = gz.force_comptime or
|
||||
tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime";
|
||||
|
||||
// Detect whether the initialization expression actually uses the
|
||||
// result location pointer.
|
||||
var init_scope = gz.makeSubBlock(scope);
|
||||
@ -2692,7 +2695,7 @@ fn varDecl(
|
||||
.type_inst = type_inst,
|
||||
.align_inst = align_inst,
|
||||
.is_const = true,
|
||||
.is_comptime = gz.force_comptime,
|
||||
.is_comptime = is_comptime,
|
||||
});
|
||||
init_scope.instructions_top = gz.instructions.items.len;
|
||||
}
|
||||
@ -2700,7 +2703,7 @@ fn varDecl(
|
||||
} else {
|
||||
const alloc = if (align_inst == .none) alloc: {
|
||||
init_scope.instructions_top = gz.instructions.items.len;
|
||||
const tag: Zir.Inst.Tag = if (gz.force_comptime)
|
||||
const tag: Zir.Inst.Tag = if (is_comptime)
|
||||
.alloc_inferred_comptime
|
||||
else
|
||||
.alloc_inferred;
|
||||
@ -2711,7 +2714,7 @@ fn varDecl(
|
||||
.type_inst = .none,
|
||||
.align_inst = align_inst,
|
||||
.is_const = true,
|
||||
.is_comptime = gz.force_comptime,
|
||||
.is_comptime = is_comptime,
|
||||
});
|
||||
init_scope.instructions_top = gz.instructions.items.len;
|
||||
break :alloc ref;
|
||||
|
||||
@ -859,3 +859,22 @@ test "debug variable type resolved through indirect zero-bit types" {
|
||||
const slice: []const T = &[_]T{};
|
||||
_ = slice;
|
||||
}
|
||||
|
||||
test "const local with comptime init through array init" {
|
||||
const E1 = enum {
|
||||
A,
|
||||
fn a() void {}
|
||||
};
|
||||
|
||||
const S = struct {
|
||||
fn declarations(comptime T: type) []const std.builtin.Type.Declaration {
|
||||
return @typeInfo(T).Enum.decls;
|
||||
}
|
||||
};
|
||||
|
||||
const decls = comptime [_][]const std.builtin.Type.Declaration{
|
||||
S.declarations(E1),
|
||||
};
|
||||
|
||||
try comptime expect(decls[0][0].name[0] == 'a');
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user