| ... | @@ -120,6 +120,8 @@ pub const Value = extern union { | ... | @@ -120,6 +120,8 @@ pub const Value = extern union { |
| 120 | /// This Tag will never be seen by machine codegen backends. It is changed into a | 120 | /// This Tag will never be seen by machine codegen backends. It is changed into a |
| 121 | /// `decl_ref` when a comptime variable goes out of scope. | 121 | /// `decl_ref` when a comptime variable goes out of scope. |
| 122 | decl_ref_mut, | 122 | decl_ref_mut, |
| | 123 | /// Behaves like `decl_ref_mut` but validates that the stored value matches the field value. |
| | 124 | comptime_field_ptr, |
| 123 | /// Pointer to a specific element of an array, vector or slice. | 125 | /// Pointer to a specific element of an array, vector or slice. |
| 124 | elem_ptr, | 126 | elem_ptr, |
| 125 | /// Pointer to a specific field of a struct or union. | 127 | /// Pointer to a specific field of a struct or union. |
| ... | @@ -316,6 +318,7 @@ pub const Value = extern union { | ... | @@ -316,6 +318,7 @@ pub const Value = extern union { |
| 316 | .aggregate => Payload.Aggregate, | 318 | .aggregate => Payload.Aggregate, |
| 317 | .@"union" => Payload.Union, | 319 | .@"union" => Payload.Union, |
| 318 | .bound_fn => Payload.BoundFn, | 320 | .bound_fn => Payload.BoundFn, |
| | 321 | .comptime_field_ptr => Payload.ComptimeFieldPtr, |
| 319 | }; | 322 | }; |
| 320 | } | 323 | } |
| 321 | | 324 | |
| ... | @@ -506,6 +509,18 @@ pub const Value = extern union { | ... | @@ -506,6 +509,18 @@ pub const Value = extern union { |
| 506 | }; | 509 | }; |
| 507 | return Value{ .ptr_otherwise = &new_payload.base }; | 510 | return Value{ .ptr_otherwise = &new_payload.base }; |
| 508 | }, | 511 | }, |
| | 512 | .comptime_field_ptr => { |
| | 513 | const payload = self.cast(Payload.ComptimeFieldPtr).?; |
| | 514 | const new_payload = try arena.create(Payload.ComptimeFieldPtr); |
| | 515 | new_payload.* = .{ |
| | 516 | .base = payload.base, |
| | 517 | .data = .{ |
| | 518 | .field_val = try payload.data.field_val.copy(arena), |
| | 519 | .field_ty = try payload.data.field_ty.copy(arena), |
| | 520 | }, |
| | 521 | }; |
| | 522 | return Value{ .ptr_otherwise = &new_payload.base }; |
| | 523 | }, |
| 509 | .elem_ptr => { | 524 | .elem_ptr => { |
| 510 | const payload = self.castTag(.elem_ptr).?; | 525 | const payload = self.castTag(.elem_ptr).?; |
| 511 | const new_payload = try arena.create(Payload.ElemPtr); | 526 | const new_payload = try arena.create(Payload.ElemPtr); |
| ... | @@ -754,6 +769,9 @@ pub const Value = extern union { | ... | @@ -754,6 +769,9 @@ pub const Value = extern union { |
| 754 | const decl_index = val.castTag(.decl_ref).?.data; | 769 | const decl_index = val.castTag(.decl_ref).?.data; |
| 755 | return out_stream.print("(decl_ref {d})", .{decl_index}); | 770 | return out_stream.print("(decl_ref {d})", .{decl_index}); |
| 756 | }, | 771 | }, |
| | 772 | .comptime_field_ptr => { |
| | 773 | return out_stream.writeAll("(comptime_field_ptr)"); |
| | 774 | }, |
| 757 | .elem_ptr => { | 775 | .elem_ptr => { |
| 758 | const elem_ptr = val.castTag(.elem_ptr).?.data; | 776 | const elem_ptr = val.castTag(.elem_ptr).?.data; |
| 759 | try out_stream.print("&[{}] ", .{elem_ptr.index}); | 777 | try out_stream.print("&[{}] ", .{elem_ptr.index}); |
| ... | @@ -1706,6 +1724,7 @@ pub const Value = extern union { | ... | @@ -1706,6 +1724,7 @@ pub const Value = extern union { |
| 1706 | .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(), | 1724 | .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(), |
| 1707 | | 1725 | |
| 1708 | .decl_ref_mut, | 1726 | .decl_ref_mut, |
| | 1727 | .comptime_field_ptr, |
| 1709 | .extern_fn, | 1728 | .extern_fn, |
| 1710 | .decl_ref, | 1729 | .decl_ref, |
| 1711 | .function, | 1730 | .function, |
| ... | @@ -1770,6 +1789,7 @@ pub const Value = extern union { | ... | @@ -1770,6 +1789,7 @@ pub const Value = extern union { |
| 1770 | .bool_true, | 1789 | .bool_true, |
| 1771 | .decl_ref, | 1790 | .decl_ref, |
| 1772 | .decl_ref_mut, | 1791 | .decl_ref_mut, |
| | 1792 | .comptime_field_ptr, |
| 1773 | .extern_fn, | 1793 | .extern_fn, |
| 1774 | .function, | 1794 | .function, |
| 1775 | .variable, | 1795 | .variable, |
| ... | @@ -2362,7 +2382,7 @@ pub const Value = extern union { | ... | @@ -2362,7 +2382,7 @@ pub const Value = extern union { |
| 2362 | | 2382 | |
| 2363 | pub fn isComptimeMutablePtr(val: Value) bool { | 2383 | pub fn isComptimeMutablePtr(val: Value) bool { |
| 2364 | return switch (val.tag()) { | 2384 | return switch (val.tag()) { |
| 2365 | .decl_ref_mut => true, | 2385 | .decl_ref_mut, .comptime_field_ptr => true, |
| 2366 | .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr), | 2386 | .elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr), |
| 2367 | .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr), | 2387 | .field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr), |
| 2368 | .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr), | 2388 | .eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr), |
| ... | @@ -2426,6 +2446,9 @@ pub const Value = extern union { | ... | @@ -2426,6 +2446,9 @@ pub const Value = extern union { |
| 2426 | const decl: Module.Decl.Index = ptr_val.pointerDecl().?; | 2446 | const decl: Module.Decl.Index = ptr_val.pointerDecl().?; |
| 2427 | std.hash.autoHash(hasher, decl); | 2447 | std.hash.autoHash(hasher, decl); |
| 2428 | }, | 2448 | }, |
| | 2449 | .comptime_field_ptr => { |
| | 2450 | std.hash.autoHash(hasher, Value.Tag.comptime_field_ptr); |
| | 2451 | }, |
| 2429 | | 2452 | |
| 2430 | .elem_ptr => { | 2453 | .elem_ptr => { |
| 2431 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; | 2454 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; |
| ... | @@ -2471,7 +2494,7 @@ pub const Value = extern union { | ... | @@ -2471,7 +2494,7 @@ pub const Value = extern union { |
| 2471 | return switch (val.tag()) { | 2494 | return switch (val.tag()) { |
| 2472 | .slice => val.castTag(.slice).?.data.ptr, | 2495 | .slice => val.castTag(.slice).?.data.ptr, |
| 2473 | // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc. | 2496 | // TODO this should require being a slice tag, and not allow decl_ref, field_ptr, etc. |
| 2474 | .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr => val, | 2497 | .decl_ref, .decl_ref_mut, .field_ptr, .elem_ptr, .comptime_field_ptr => val, |
| 2475 | else => unreachable, | 2498 | else => unreachable, |
| 2476 | }; | 2499 | }; |
| 2477 | } | 2500 | } |
| ... | @@ -2497,6 +2520,14 @@ pub const Value = extern union { | ... | @@ -2497,6 +2520,14 @@ pub const Value = extern union { |
| 2497 | return 1; | 2520 | return 1; |
| 2498 | } | 2521 | } |
| 2499 | }, | 2522 | }, |
| | 2523 | .comptime_field_ptr => { |
| | 2524 | const payload = val.castTag(.comptime_field_ptr).?.data; |
| | 2525 | if (payload.field_ty.zigTypeTag() == .Array) { |
| | 2526 | return payload.field_ty.arrayLen(); |
| | 2527 | } else { |
| | 2528 | return 1; |
| | 2529 | } |
| | 2530 | }, |
| 2500 | else => unreachable, | 2531 | else => unreachable, |
| 2501 | }; | 2532 | }; |
| 2502 | } | 2533 | } |
| ... | @@ -2587,6 +2618,7 @@ pub const Value = extern union { | ... | @@ -2587,6 +2618,7 @@ pub const Value = extern union { |
| 2587 | | 2618 | |
| 2588 | .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer), | 2619 | .decl_ref => return mod.declPtr(val.castTag(.decl_ref).?.data).val.elemValueAdvanced(mod, index, arena, buffer), |
| 2589 | .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer), | 2620 | .decl_ref_mut => return mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.elemValueAdvanced(mod, index, arena, buffer), |
| | 2621 | .comptime_field_ptr => return val.castTag(.comptime_field_ptr).?.data.field_val.elemValueAdvanced(mod, index, arena, buffer), |
| 2590 | .elem_ptr => { | 2622 | .elem_ptr => { |
| 2591 | const data = val.castTag(.elem_ptr).?.data; | 2623 | const data = val.castTag(.elem_ptr).?.data; |
| 2592 | return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer); | 2624 | return data.array_ptr.elemValueAdvanced(mod, index + data.index, arena, buffer); |
| ... | @@ -2623,6 +2655,7 @@ pub const Value = extern union { | ... | @@ -2623,6 +2655,7 @@ pub const Value = extern union { |
| 2623 | | 2655 | |
| 2624 | .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end), | 2656 | .decl_ref => sliceArray(mod.declPtr(val.castTag(.decl_ref).?.data).val, mod, arena, start, end), |
| 2625 | .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end), | 2657 | .decl_ref_mut => sliceArray(mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val, mod, arena, start, end), |
| | 2658 | .comptime_field_ptr => sliceArray(val.castTag(.comptime_field_ptr).?.data.field_val, mod, arena, start, end), |
| 2626 | .elem_ptr => blk: { | 2659 | .elem_ptr => blk: { |
| 2627 | const elem_ptr = val.castTag(.elem_ptr).?.data; | 2660 | const elem_ptr = val.castTag(.elem_ptr).?.data; |
| 2628 | break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index); | 2661 | break :blk sliceArray(elem_ptr.array_ptr, mod, arena, start + elem_ptr.index, end + elem_ptr.index); |
| ... | @@ -4742,6 +4775,14 @@ pub const Value = extern union { | ... | @@ -4742,6 +4775,14 @@ pub const Value = extern union { |
| 4742 | }, | 4775 | }, |
| 4743 | }; | 4776 | }; |
| 4744 | | 4777 | |
| | 4778 | pub const ComptimeFieldPtr = struct { |
| | 4779 | base: Payload, |
| | 4780 | data: struct { |
| | 4781 | field_val: Value, |
| | 4782 | field_ty: Type, |
| | 4783 | }, |
| | 4784 | }; |
| | 4785 | |
| 4745 | pub const ElemPtr = struct { | 4786 | pub const ElemPtr = struct { |
| 4746 | pub const base_tag = Tag.elem_ptr; | 4787 | pub const base_tag = Tag.elem_ptr; |
| 4747 | | 4788 | |