| author | |
| committer | |
| log | 93e53d1e00793d769d4ee39b3cbfd0c88257687d |
| tree | 615f4e4fa503210282bd0bdf313ff1f7210bceb0 |
| parent | 6917a8c25824d12f00327171b583d6cd9a830c29 |
| signature |
This introduces a new ZIR instruction, `vec_elem_type`.
Co-Authored-By: Ali Chraghi <alichraghi@proton.me>
Resolves: #165675 files changed, 36 insertions(+), 7 deletions(-)
src/AstGen.zig+2-7| ... | @@ -2569,6 +2569,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2569,6 +2569,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2569 | .array_type_sentinel, | 2569 | .array_type_sentinel, |
| 2570 | .elem_type_index, | 2570 | .elem_type_index, |
| 2571 | .elem_type, | 2571 | .elem_type, |
| 2572 | .vector_elem_type, | ||
| 2572 | .vector_type, | 2573 | .vector_type, |
| 2573 | .indexable_ptr_len, | 2574 | .indexable_ptr_len, |
| 2574 | .anyframe_type, | 2575 | .anyframe_type, |
| ... | @@ -8624,13 +8625,7 @@ fn builtinCall( | ... | @@ -8624,13 +8625,7 @@ fn builtinCall( |
| 8624 | 8625 | ||
| 8625 | .splat => { | 8626 | .splat => { |
| 8626 | const result_type = try ri.rl.resultType(gz, node, "@splat"); | 8627 | const result_type = try ri.rl.resultType(gz, node, "@splat"); |
| 8627 | const elem_type = try gz.add(.{ | 8628 | const elem_type = try gz.addUnNode(.vector_elem_type, result_type, node); |
| 8628 | .tag = .elem_type_index, | ||
| 8629 | .data = .{ .bin = .{ | ||
| 8630 | .lhs = result_type, | ||
| 8631 | .rhs = @as(Zir.Inst.Ref, @enumFromInt(0)), | ||
| 8632 | } }, | ||
| 8633 | }); | ||
| 8634 | const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]); | 8629 | const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]); |
| 8635 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ | 8630 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ |
| 8636 | .lhs = result_type, | 8631 | .lhs = result_type, |
src/Sema.zig+18| ... | @@ -1022,6 +1022,7 @@ fn analyzeBodyInner( | ... | @@ -1022,6 +1022,7 @@ fn analyzeBodyInner( |
| 1022 | .elem_val_node => try sema.zirElemValNode(block, inst), | 1022 | .elem_val_node => try sema.zirElemValNode(block, inst), |
| 1023 | .elem_type_index => try sema.zirElemTypeIndex(block, inst), | 1023 | .elem_type_index => try sema.zirElemTypeIndex(block, inst), |
| 1024 | .elem_type => try sema.zirElemType(block, inst), | 1024 | .elem_type => try sema.zirElemType(block, inst), |
| 1025 | .vector_elem_type => try sema.zirVectorElemType(block, inst), | ||
| 1025 | .enum_literal => try sema.zirEnumLiteral(block, inst), | 1026 | .enum_literal => try sema.zirEnumLiteral(block, inst), |
| 1026 | .int_from_enum => try sema.zirIntFromEnum(block, inst), | 1027 | .int_from_enum => try sema.zirIntFromEnum(block, inst), |
| 1027 | .enum_from_int => try sema.zirEnumFromInt(block, inst), | 1028 | .enum_from_int => try sema.zirEnumFromInt(block, inst), |
| ... | @@ -7804,6 +7805,23 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -7804,6 +7805,23 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 7804 | return sema.addType(ptr_ty.childType(mod)); | 7805 | return sema.addType(ptr_ty.childType(mod)); |
| 7805 | } | 7806 | } |
| 7806 | 7807 | ||
| 7808 | fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | ||
| 7809 | const mod = sema.mod; | ||
| 7810 | const un_node = sema.code.instructions.items(.data)[inst].un_node; | ||
| 7811 | const vec_ty = sema.resolveType(block, .unneeded, un_node.operand) catch |err| switch (err) { | ||
| 7812 | // Since this is a ZIR instruction that returns a type, encountering | ||
| 7813 | // generic poison should not result in a failed compilation, but the | ||
| 7814 | // generic poison type. This prevents unnecessary failures when | ||
| 7815 | // constructing types at compile-time. | ||
| 7816 | error.GenericPoison => return .generic_poison_type, | ||
| 7817 | else => |e| return e, | ||
| 7818 | }; | ||
| 7819 | if (!vec_ty.isVector(mod)) { | ||
| 7820 | return sema.fail(block, un_node.src(), "expected vector type, found '{}'", .{vec_ty.fmt(mod)}); | ||
| 7821 | } | ||
| 7822 | return sema.addType(vec_ty.childType(mod)); | ||
| 7823 | } | ||
| 7824 | |||
| 7807 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 7825 | fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 7808 | const mod = sema.mod; | 7826 | const mod = sema.mod; |
| 7809 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 7827 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
src/Zir.zig+6| ... | @@ -248,6 +248,9 @@ pub const Inst = struct { | ... | @@ -248,6 +248,9 @@ pub const Inst = struct { |
| 248 | /// Given a pointer type, returns its element type. | 248 | /// Given a pointer type, returns its element type. |
| 249 | /// Uses the `un_node` field. | 249 | /// Uses the `un_node` field. |
| 250 | elem_type, | 250 | elem_type, |
| 251 | /// Given a vector type, returns its element type. | ||
| 252 | /// Uses the `un_node` field. | ||
| 253 | vector_elem_type, | ||
| 251 | /// Given a pointer to an indexable object, returns the len property. This is | 254 | /// Given a pointer to an indexable object, returns the len property. This is |
| 252 | /// used by for loops. This instruction also emits a for-loop specific compile | 255 | /// used by for loops. This instruction also emits a for-loop specific compile |
| 253 | /// error if the indexable object is not indexable. | 256 | /// error if the indexable object is not indexable. |
| ... | @@ -1029,6 +1032,7 @@ pub const Inst = struct { | ... | @@ -1029,6 +1032,7 @@ pub const Inst = struct { |
| 1029 | .vector_type, | 1032 | .vector_type, |
| 1030 | .elem_type_index, | 1033 | .elem_type_index, |
| 1031 | .elem_type, | 1034 | .elem_type, |
| 1035 | .vector_elem_type, | ||
| 1032 | .indexable_ptr_len, | 1036 | .indexable_ptr_len, |
| 1033 | .anyframe_type, | 1037 | .anyframe_type, |
| 1034 | .as, | 1038 | .as, |
| ... | @@ -1334,6 +1338,7 @@ pub const Inst = struct { | ... | @@ -1334,6 +1338,7 @@ pub const Inst = struct { |
| 1334 | .vector_type, | 1338 | .vector_type, |
| 1335 | .elem_type_index, | 1339 | .elem_type_index, |
| 1336 | .elem_type, | 1340 | .elem_type, |
| 1341 | .vector_elem_type, | ||
| 1337 | .indexable_ptr_len, | 1342 | .indexable_ptr_len, |
| 1338 | .anyframe_type, | 1343 | .anyframe_type, |
| 1339 | .as, | 1344 | .as, |
| ... | @@ -1565,6 +1570,7 @@ pub const Inst = struct { | ... | @@ -1565,6 +1570,7 @@ pub const Inst = struct { |
| 1565 | .vector_type = .pl_node, | 1570 | .vector_type = .pl_node, |
| 1566 | .elem_type_index = .bin, | 1571 | .elem_type_index = .bin, |
| 1567 | .elem_type = .un_node, | 1572 | .elem_type = .un_node, |
| 1573 | .vector_elem_type = .un_node, | ||
| 1568 | .indexable_ptr_len = .un_node, | 1574 | .indexable_ptr_len = .un_node, |
| 1569 | .anyframe_type = .un_node, | 1575 | .anyframe_type = .un_node, |
| 1570 | .as = .bin, | 1576 | .as = .bin, |
src/print_zir.zig+1| ... | @@ -155,6 +155,7 @@ const Writer = struct { | ... | @@ -155,6 +155,7 @@ const Writer = struct { |
| 155 | .alloc_mut, | 155 | .alloc_mut, |
| 156 | .alloc_comptime_mut, | 156 | .alloc_comptime_mut, |
| 157 | .elem_type, | 157 | .elem_type, |
| 158 | .vector_elem_type, | ||
| 158 | .indexable_ptr_len, | 159 | .indexable_ptr_len, |
| 159 | .anyframe_type, | 160 | .anyframe_type, |
| 160 | .bit_not, | 161 | .bit_not, |
test/cases/compile_errors/splat_result_type_non_vector.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | export fn f() void { | ||
| 2 | _ = @as(u32, @splat(5)); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:18: error: expected vector type, found 'u32' | ||