authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-11 12:18:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-11 12:18:04-07:00
log9360cfebc722d99a54b576fff8bcfc0f0354ad41
tree2c32d307cf752a12bda8eadb450dd03f73bbdecb
parent13123afedbf05cf4646a7e5f39a95a4b06b45285

Sema: type safety for "runtime_index" field

This commit does not change any behavior, but changes the type of the runtime_index field from u32 to a non-exhaustive enum. This allows us to put `std.math.maxInt(u32)` only in the enum type definition and give it an official meaning.

2 files changed, 21 insertions(+), 12 deletions(-)

src/Sema.zig+10-11
...@@ -135,7 +135,7 @@ pub const Block = struct {...@@ -135,7 +135,7 @@ pub const Block = struct {
135 src_decl: Decl.Index,135 src_decl: Decl.Index,
136 /// Non zero if a non-inline loop or a runtime conditional have been encountered.136 /// Non zero if a non-inline loop or a runtime conditional have been encountered.
137 /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index.137 /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index.
138 runtime_index: u32 = 0,138 runtime_index: Value.RuntimeIndex = .zero,
139139
140 is_comptime: bool,140 is_comptime: bool,
141 is_typeof: bool = false,141 is_typeof: bool = false,
...@@ -4276,7 +4276,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -4276,7 +4276,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
4276 child_block.label = &label;4276 child_block.label = &label;
4277 child_block.runtime_cond = null;4277 child_block.runtime_cond = null;
4278 child_block.runtime_loop = src;4278 child_block.runtime_loop = src;
4279 child_block.runtime_index += 1;4279 child_block.runtime_index.increment();
4280 const merges = &child_block.label.?.merges;4280 const merges = &child_block.label.?.merges;
42814281
4282 defer child_block.instructions.deinit(gpa);4282 defer child_block.instructions.deinit(gpa);
...@@ -4795,7 +4795,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -4795,7 +4795,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
4795 const br_ref = try start_block.addBr(label.merges.block_inst, operand);4795 const br_ref = try start_block.addBr(label.merges.block_inst, operand);
4796 try label.merges.results.append(sema.gpa, operand);4796 try label.merges.results.append(sema.gpa, operand);
4797 try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);4797 try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
4798 block.runtime_index += 1;4798 block.runtime_index.increment();
4799 if (block.runtime_cond == null and block.runtime_loop == null) {4799 if (block.runtime_cond == null and block.runtime_loop == null) {
4800 block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;4800 block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;
4801 block.runtime_loop = start_block.runtime_loop;4801 block.runtime_loop = start_block.runtime_loop;
...@@ -8650,7 +8650,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8650,7 +8650,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8650 var case_block = child_block.makeSubBlock();8650 var case_block = child_block.makeSubBlock();
8651 case_block.runtime_loop = null;8651 case_block.runtime_loop = null;
8652 case_block.runtime_cond = operand_src;8652 case_block.runtime_cond = operand_src;
8653 case_block.runtime_index += 1;8653 case_block.runtime_index.increment();
8654 defer case_block.instructions.deinit(gpa);8654 defer case_block.instructions.deinit(gpa);
86558655
8656 var extra_index: usize = special.end;8656 var extra_index: usize = special.end;
...@@ -12938,7 +12938,7 @@ fn zirBoolBr(...@@ -12938,7 +12938,7 @@ fn zirBoolBr(
12938 var child_block = parent_block.makeSubBlock();12938 var child_block = parent_block.makeSubBlock();
12939 child_block.runtime_loop = null;12939 child_block.runtime_loop = null;
12940 child_block.runtime_cond = lhs_src;12940 child_block.runtime_cond = lhs_src;
12941 child_block.runtime_index += 1;12941 child_block.runtime_index.increment();
12942 defer child_block.instructions.deinit(gpa);12942 defer child_block.instructions.deinit(gpa);
1294312943
12944 var then_block = child_block.makeSubBlock();12944 var then_block = child_block.makeSubBlock();
...@@ -13066,7 +13066,7 @@ fn zirCondbr(...@@ -13066,7 +13066,7 @@ fn zirCondbr(
13066 var sub_block = parent_block.makeSubBlock();13066 var sub_block = parent_block.makeSubBlock();
13067 sub_block.runtime_loop = null;13067 sub_block.runtime_loop = null;
13068 sub_block.runtime_cond = cond_src;13068 sub_block.runtime_cond = cond_src;
13069 sub_block.runtime_index += 1;13069 sub_block.runtime_index.increment();
13070 defer sub_block.instructions.deinit(gpa);13070 defer sub_block.instructions.deinit(gpa);
1307113071
13072 _ = sema.analyzeBodyInner(&sub_block, then_body) catch |err| switch (err) {13072 _ = sema.analyzeBodyInner(&sub_block, then_body) catch |err| switch (err) {
...@@ -13263,7 +13263,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi...@@ -13263,7 +13263,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
13263 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);13263 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);
13264 try labeled_block.label.merges.results.append(sema.gpa, operand);13264 try labeled_block.label.merges.results.append(sema.gpa, operand);
13265 try labeled_block.label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);13265 try labeled_block.label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
13266 labeled_block.block.runtime_index += 1;13266 labeled_block.block.runtime_index.increment();
13267 if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) {13267 if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) {
13268 labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop;13268 labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop;
13269 labeled_block.block.runtime_loop = child_block.runtime_loop;13269 labeled_block.block.runtime_loop = child_block.runtime_loop;
...@@ -15812,7 +15812,7 @@ fn checkComptimeVarStore(...@@ -15812,7 +15812,7 @@ fn checkComptimeVarStore(
15812 src: LazySrcLoc,15812 src: LazySrcLoc,
15813 decl_ref_mut: Value.Payload.DeclRefMut.Data,15813 decl_ref_mut: Value.Payload.DeclRefMut.Data,
15814) CompileError!void {15814) CompileError!void {
15815 if (decl_ref_mut.runtime_index < block.runtime_index) {15815 if (@enumToInt(decl_ref_mut.runtime_index) < @enumToInt(block.runtime_index)) {
15816 if (block.runtime_cond) |cond_src| {15816 if (block.runtime_cond) |cond_src| {
15817 const msg = msg: {15817 const msg = msg: {
15818 const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{});15818 const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{});
...@@ -20526,8 +20526,7 @@ fn storePtrVal(...@@ -20526,8 +20526,7 @@ fn storePtrVal(
2052620526
20527 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);20527 const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, mut_kit.ty, 0);
2052820528
20529 if (mut_kit.decl_ref_mut.runtime_index == std.math.maxInt(u32)) {20529 if (mut_kit.decl_ref_mut.runtime_index == .comptime_field_ptr) {
20530 // Special case for comptime field ptr.
20531 if (!mut_kit.val.eql(bitcasted_val, mut_kit.ty, sema.mod)) {20530 if (!mut_kit.val.eql(bitcasted_val, mut_kit.ty, sema.mod)) {
20532 return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});20531 return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{});
20533 }20532 }
...@@ -20590,7 +20589,7 @@ fn beginComptimePtrMutation(...@@ -20590,7 +20589,7 @@ fn beginComptimePtrMutation(
20590 return ComptimePtrMutationKit{20589 return ComptimePtrMutationKit{
20591 .decl_ref_mut = .{20590 .decl_ref_mut = .{
20592 .decl_index = @intToEnum(Module.Decl.Index, 0),20591 .decl_index = @intToEnum(Module.Decl.Index, 0),
20593 .runtime_index = std.math.maxInt(u32),20592 .runtime_index = .comptime_field_ptr,
20594 },20593 },
20595 .val = duped,20594 .val = duped,
20596 .ty = payload.field_ty,20595 .ty = payload.field_ty,
src/value.zig+11-1
...@@ -4768,7 +4768,7 @@ pub const Value = extern union {...@@ -4768,7 +4768,7 @@ pub const Value = extern union {
47684768
4769 pub const Data = struct {4769 pub const Data = struct {
4770 decl_index: Module.Decl.Index,4770 decl_index: Module.Decl.Index,
4771 runtime_index: u32,4771 runtime_index: RuntimeIndex,
4772 };4772 };
4773 };4773 };
47744774
...@@ -4965,6 +4965,16 @@ pub const Value = extern union {...@@ -4965,6 +4965,16 @@ pub const Value = extern union {
4965 pub fn makeBool(x: bool) Value {4965 pub fn makeBool(x: bool) Value {
4966 return if (x) Value.@"true" else Value.@"false";4966 return if (x) Value.@"true" else Value.@"false";
4967 }4967 }
4968
4969 pub const RuntimeIndex = enum(u32) {
4970 zero = 0,
4971 comptime_field_ptr = std.math.maxInt(u32),
4972 _,
4973
4974 pub fn increment(ri: *RuntimeIndex) void {
4975 ri.* = @intToEnum(RuntimeIndex, @enumToInt(ri.*) + 1);
4976 }
4977 };
4968};4978};
49694979
4970var negative_one_payload: Value.Payload.I64 = .{4980var negative_one_payload: Value.Payload.I64 = .{